Skip to content

Commit 996c1cc

Browse files
committed
Fix Auto-Startup for @JmsListener
Ignore container's auto-startup once the context is refreshed. Issue: SPR-14015
1 parent ad7285d commit 996c1cc

File tree

4 files changed

+85
-8
lines changed

4 files changed

+85
-8
lines changed

spring-jms/src/main/java/org/springframework/jms/config/JmsListenerEndpointRegistry.java

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2015 the original author or authors.
2+
* Copyright 2002-2016 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -26,10 +26,15 @@
2626
import org.apache.commons.logging.Log;
2727
import org.apache.commons.logging.LogFactory;
2828

29+
import org.springframework.beans.BeansException;
2930
import org.springframework.beans.factory.BeanInitializationException;
3031
import org.springframework.beans.factory.DisposableBean;
3132
import org.springframework.beans.factory.InitializingBean;
33+
import org.springframework.context.ApplicationContext;
34+
import org.springframework.context.ApplicationContextAware;
35+
import org.springframework.context.ApplicationListener;
3236
import org.springframework.context.SmartLifecycle;
37+
import org.springframework.context.event.ContextRefreshedEvent;
3338
import org.springframework.jms.listener.MessageListenerContainer;
3439
import org.springframework.util.Assert;
3540

@@ -53,7 +58,8 @@
5358
* @see MessageListenerContainer
5459
* @see JmsListenerContainerFactory
5560
*/
56-
public class JmsListenerEndpointRegistry implements DisposableBean, SmartLifecycle {
61+
public class JmsListenerEndpointRegistry implements DisposableBean, SmartLifecycle,
62+
ApplicationContextAware, ApplicationListener<ContextRefreshedEvent> {
5763

5864
protected final Log logger = LogFactory.getLog(getClass());
5965

@@ -62,6 +68,15 @@ public class JmsListenerEndpointRegistry implements DisposableBean, SmartLifecyc
6268

6369
private int phase = Integer.MAX_VALUE;
6470

71+
private ApplicationContext applicationContext;
72+
73+
private boolean contextRefreshed;
74+
75+
@Override
76+
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
77+
this.applicationContext = applicationContext;
78+
}
79+
6580

6681
/**
6782
* Return the {@link MessageListenerContainer} with the specified id or
@@ -181,6 +196,13 @@ public void destroy() {
181196
}
182197

183198

199+
@Override
200+
public void onApplicationEvent(ContextRefreshedEvent event) {
201+
if (event.getApplicationContext().equals(this.applicationContext)) {
202+
this.contextRefreshed = true;
203+
}
204+
}
205+
184206
// Delegating implementation of SmartLifecycle
185207

186208
@Override
@@ -228,11 +250,11 @@ public boolean isRunning() {
228250

229251
/**
230252
* Start the specified {@link MessageListenerContainer} if it should be started
231-
* on startup.
253+
* on startup or when start is called explicitly after startup.
232254
* @see MessageListenerContainer#isAutoStartup()
233255
*/
234-
private static void startIfNecessary(MessageListenerContainer listenerContainer) {
235-
if (listenerContainer.isAutoStartup()) {
256+
private void startIfNecessary(MessageListenerContainer listenerContainer) {
257+
if (this.contextRefreshed || listenerContainer.isAutoStartup()) {
236258
listenerContainer.start();
237259
}
238260
}

spring-jms/src/test/java/org/springframework/jms/annotation/EnableJmsTests.java

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,31 @@ public void defaultContainerFactory() {
109109
testDefaultContainerFactoryConfiguration(context);
110110
}
111111

112+
@Test
113+
public void containerAreStartedByDefault() {
114+
ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(
115+
EnableJmsDefaultContainerFactoryConfig.class, DefaultBean.class);
116+
JmsListenerContainerTestFactory factory =
117+
context.getBean(JmsListenerContainerTestFactory.class);
118+
MessageListenerTestContainer container = factory.getListenerContainers().get(0);
119+
assertTrue(container.isAutoStartup());
120+
assertTrue(container.isStarted());
121+
}
122+
123+
@Test
124+
public void containerCanBeStarterViaTheRegistry() {
125+
ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(
126+
EnableJmsAutoStartupFalseConfig.class, DefaultBean.class);
127+
JmsListenerContainerTestFactory factory =
128+
context.getBean(JmsListenerContainerTestFactory.class);
129+
MessageListenerTestContainer container = factory.getListenerContainers().get(0);
130+
assertFalse(container.isAutoStartup());
131+
assertFalse(container.isStarted());
132+
JmsListenerEndpointRegistry registry = context.getBean(JmsListenerEndpointRegistry.class);
133+
registry.start();
134+
assertTrue(container.isStarted());
135+
}
136+
112137
@Override
113138
@Test
114139
public void jmsHandlerMethodFactoryConfiguration() throws JMSException {
@@ -314,6 +339,23 @@ public JmsListenerContainerTestFactory defaultFactory() {
314339
}
315340
}
316341

342+
@Configuration
343+
@EnableJms
344+
static class EnableJmsAutoStartupFalseConfig implements JmsListenerConfigurer {
345+
346+
@Override
347+
public void configureJmsListeners(JmsListenerEndpointRegistrar registrar) {
348+
registrar.setContainerFactory(simpleFactory());
349+
}
350+
351+
@Bean
352+
public JmsListenerContainerTestFactory simpleFactory() {
353+
JmsListenerContainerTestFactory factory = new JmsListenerContainerTestFactory();
354+
factory.setAutoStartup(false);
355+
return factory;
356+
}
357+
}
358+
317359

318360
@Component
319361
@Lazy

spring-jms/src/test/java/org/springframework/jms/config/JmsListenerContainerTestFactory.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2015 the original author or authors.
2+
* Copyright 2002-2016 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -26,9 +26,15 @@
2626
*/
2727
public class JmsListenerContainerTestFactory implements JmsListenerContainerFactory<MessageListenerTestContainer> {
2828

29+
private boolean autoStartup = true;
30+
2931
private final Map<String, MessageListenerTestContainer> listenerContainers =
3032
new LinkedHashMap<>();
3133

34+
public void setAutoStartup(boolean autoStartup) {
35+
this.autoStartup = autoStartup;
36+
}
37+
3238
public List<MessageListenerTestContainer> getListenerContainers() {
3339
return new ArrayList<>(this.listenerContainers.values());
3440
}
@@ -40,6 +46,7 @@ public MessageListenerTestContainer getListenerContainer(String id) {
4046
@Override
4147
public MessageListenerTestContainer createListenerContainer(JmsListenerEndpoint endpoint) {
4248
MessageListenerTestContainer container = new MessageListenerTestContainer(endpoint);
49+
container.setAutoStartup(this.autoStartup);
4350
this.listenerContainers.put(endpoint.getId(), container);
4451
return container;
4552
}

spring-jms/src/test/java/org/springframework/jms/config/MessageListenerTestContainer.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2015 the original author or authors.
2+
* Copyright 2002-2016 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -31,6 +31,8 @@ public class MessageListenerTestContainer
3131

3232
private final JmsListenerEndpoint endpoint;
3333

34+
private boolean autoStartup = true;
35+
3436
private boolean startInvoked;
3537

3638
private boolean initializationInvoked;
@@ -43,6 +45,10 @@ public class MessageListenerTestContainer
4345
this.endpoint = endpoint;
4446
}
4547

48+
public void setAutoStartup(boolean autoStartup) {
49+
this.autoStartup = autoStartup;
50+
}
51+
4652
public JmsListenerEndpoint getEndpoint() {
4753
return endpoint;
4854
}
@@ -86,7 +92,7 @@ public int getPhase() {
8692

8793
@Override
8894
public boolean isAutoStartup() {
89-
return true;
95+
return this.autoStartup;
9096
}
9197

9298
@Override

0 commit comments

Comments
 (0)