|
1 | 1 | /*
|
2 |
| - * Copyright 2002-2014 the original author or authors. |
| 2 | + * Copyright 2002-2015 the original author or authors. |
3 | 3 | *
|
4 | 4 | * Licensed under the Apache License, Version 2.0 (the "License");
|
5 | 5 | * you may not use this file except in compliance with the License.
|
|
18 | 18 |
|
19 | 19 | import java.util.Collection;
|
20 | 20 | import java.util.Collections;
|
21 |
| -import java.util.LinkedHashMap; |
22 | 21 | import java.util.Map;
|
| 22 | +import java.util.concurrent.ConcurrentHashMap; |
23 | 23 | import java.util.concurrent.atomic.AtomicInteger;
|
24 | 24 |
|
25 | 25 | import org.apache.commons.logging.Log;
|
@@ -57,7 +57,7 @@ public class JmsListenerEndpointRegistry implements DisposableBean, SmartLifecyc
|
57 | 57 | protected final Log logger = LogFactory.getLog(getClass());
|
58 | 58 |
|
59 | 59 | private final Map<String, MessageListenerContainer> listenerContainers =
|
60 |
| - new LinkedHashMap<String, MessageListenerContainer>(); |
| 60 | + new ConcurrentHashMap<String, MessageListenerContainer>(); |
61 | 61 |
|
62 | 62 | private int phase = Integer.MAX_VALUE;
|
63 | 63 |
|
@@ -86,21 +86,43 @@ public Collection<MessageListenerContainer> getListenerContainers() {
|
86 | 86 | * Create a message listener container for the given {@link JmsListenerEndpoint}.
|
87 | 87 | * <p>This create the necessary infrastructure to honor that endpoint
|
88 | 88 | * with regards to its configuration.
|
| 89 | + * <p>The {@code startImmediately} flag determines if the container should be |
| 90 | + * started immediately. |
89 | 91 | * @param endpoint the endpoint to add
|
| 92 | + * @param factory the listener factory to use |
| 93 | + * @param startImmediately start the container immediately if necessary |
90 | 94 | * @see #getListenerContainers()
|
91 | 95 | * @see #getListenerContainer(String)
|
92 | 96 | */
|
93 |
| - public void registerListenerContainer(JmsListenerEndpoint endpoint, JmsListenerContainerFactory<?> factory) { |
| 97 | + public void registerListenerContainer(JmsListenerEndpoint endpoint, JmsListenerContainerFactory<?> factory, |
| 98 | + boolean startImmediately) { |
| 99 | + |
94 | 100 | Assert.notNull(endpoint, "Endpoint must not be null");
|
95 | 101 | Assert.notNull(factory, "Factory must not be null");
|
96 | 102 |
|
97 | 103 | String id = endpoint.getId();
|
98 | 104 | Assert.notNull(id, "Endpoint id must not be null");
|
99 |
| - Assert.state(!this.listenerContainers.containsKey(id), |
100 |
| - "Another endpoint is already registered with id '" + id + "'"); |
| 105 | + synchronized (this.listenerContainers) { |
| 106 | + Assert.state(!this.listenerContainers.containsKey(id), |
| 107 | + "Another endpoint is already registered with id '" + id + "'"); |
| 108 | + MessageListenerContainer container = createListenerContainer(endpoint, factory); |
| 109 | + this.listenerContainers.put(id, container); |
| 110 | + if (startImmediately) { |
| 111 | + startIfNecessary(container); |
| 112 | + } |
| 113 | + } |
| 114 | + } |
101 | 115 |
|
102 |
| - MessageListenerContainer container = createListenerContainer(endpoint, factory); |
103 |
| - this.listenerContainers.put(id, container); |
| 116 | + /** |
| 117 | + * Create a message listener container for the given {@link JmsListenerEndpoint}. |
| 118 | + * <p>This create the necessary infrastructure to honor that endpoint |
| 119 | + * with regards to its configuration. |
| 120 | + * @param endpoint the endpoint to add |
| 121 | + * @param factory the listener factory to use |
| 122 | + * @see #registerListenerContainer(JmsListenerEndpoint, JmsListenerContainerFactory, boolean) |
| 123 | + */ |
| 124 | + public void registerListenerContainer(JmsListenerEndpoint endpoint, JmsListenerContainerFactory<?> factory) { |
| 125 | + registerListenerContainer(endpoint, factory, false); |
104 | 126 | }
|
105 | 127 |
|
106 | 128 | /**
|
@@ -163,9 +185,7 @@ public boolean isAutoStartup() {
|
163 | 185 | @Override
|
164 | 186 | public void start() {
|
165 | 187 | for (MessageListenerContainer listenerContainer : getListenerContainers()) {
|
166 |
| - if (listenerContainer.isAutoStartup()) { |
167 |
| - listenerContainer.start(); |
168 |
| - } |
| 188 | + startIfNecessary(listenerContainer); |
169 | 189 | }
|
170 | 190 | }
|
171 | 191 |
|
@@ -195,6 +215,17 @@ public boolean isRunning() {
|
195 | 215 | return false;
|
196 | 216 | }
|
197 | 217 |
|
| 218 | + /** |
| 219 | + * Start the specified {@link MessageListenerContainer} if it should be started |
| 220 | + * on startup. |
| 221 | + * @see MessageListenerContainer#isAutoStartup() |
| 222 | + */ |
| 223 | + private static void startIfNecessary(MessageListenerContainer listenerContainer) { |
| 224 | + if (listenerContainer.isAutoStartup()) { |
| 225 | + listenerContainer.start(); |
| 226 | + } |
| 227 | + } |
| 228 | + |
198 | 229 |
|
199 | 230 | private static class AggregatingCallback implements Runnable {
|
200 | 231 |
|
|
0 commit comments