24
24
import java .util .Set ;
25
25
import java .util .concurrent .ConcurrentHashMap ;
26
26
import java .util .concurrent .atomic .AtomicInteger ;
27
+ import java .util .concurrent .locks .ReentrantLock ;
27
28
28
29
import org .springframework .beans .BeansException ;
29
30
import org .springframework .beans .factory .BeanInitializationException ;
57
58
* @param <E> listener endpoint type.
58
59
* @author Soby Chacko
59
60
* @author Christophe Bornet
61
+ * @author Chris Bono
60
62
*/
61
63
public class GenericListenerEndpointRegistry <C extends MessageListenerContainer , E extends ListenerEndpoint <C >>
62
64
implements PulsarListenerContainerRegistry , DisposableBean , SmartLifecycle , ApplicationContextAware ,
@@ -66,6 +68,8 @@ public class GenericListenerEndpointRegistry<C extends MessageListenerContainer,
66
68
67
69
private final Map <String , C > listenerContainers = new ConcurrentHashMap <>();
68
70
71
+ private final ReentrantLock containersLock = new ReentrantLock ();
72
+
69
73
private ConfigurableApplicationContext applicationContext ;
70
74
71
75
private int phase = C .DEFAULT_PHASE ;
@@ -118,18 +122,18 @@ public void registerListenerContainer(E endpoint, ListenerContainerFactory<? ext
118
122
boolean startImmediately ) {
119
123
Assert .notNull (endpoint , "Endpoint must not be null" );
120
124
Assert .notNull (factory , "Factory must not be null" );
121
-
122
- String subscriptionName = endpoint .getSubscriptionName ();
123
125
String id = endpoint .getId ();
124
-
125
- Assert .hasText (subscriptionName , "Endpoint id must not be empty" );
126
-
127
- synchronized (this .listenerContainers ) {
126
+ Assert .hasText (id , "Endpoint id must not be empty" );
127
+ this .containersLock .lock ();
128
+ try {
128
129
Assert .state (!this .listenerContainers .containsKey (id ),
129
- "Another endpoint is already registered with id '" + subscriptionName + "'" );
130
+ "Another endpoint is already registered with id '" + id + "'" );
130
131
C container = createListenerContainer (endpoint , factory );
131
132
this .listenerContainers .put (id , container );
132
133
}
134
+ finally {
135
+ this .containersLock .unlock ();
136
+ }
133
137
}
134
138
135
139
protected C createListenerContainer (E endpoint , ListenerContainerFactory <? extends C , E > factory ) {
@@ -146,10 +150,7 @@ protected C createListenerContainer(E endpoint, ListenerContainerFactory<? exten
146
150
}
147
151
148
152
int containerPhase = listenerContainer .getPhase ();
149
- if (listenerContainer .isAutoStartup () && containerPhase != C .DEFAULT_PHASE ) { // a
150
- // custom
151
- // phase
152
- // value
153
+ if (listenerContainer .isAutoStartup () && containerPhase != C .DEFAULT_PHASE ) {
153
154
if (this .phase != C .DEFAULT_PHASE && this .phase != containerPhase ) {
154
155
throw new IllegalStateException ("Encountered phase mismatch between container "
155
156
+ "factory definitions: " + this .phase + " vs " + containerPhase );
0 commit comments