diff --git a/spring-context/src/main/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessor.java b/spring-context/src/main/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessor.java
index 8719d5a0f32..5509dd53aba 100644
--- a/spring-context/src/main/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessor.java
+++ b/spring-context/src/main/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2013 the original author or authors.
+ * Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,13 +23,14 @@ import java.util.TimeZone;
import java.util.concurrent.ScheduledExecutorService;
import org.springframework.aop.support.AopUtils;
+import org.springframework.beans.factory.BeanFactory;
+import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.DisposableBean;
+import org.springframework.beans.factory.ListableBeanFactory;
+import org.springframework.beans.factory.SmartInitializingSingleton;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ApplicationContext;
-import org.springframework.context.ApplicationContextAware;
-import org.springframework.context.ApplicationListener;
import org.springframework.context.EmbeddedValueResolverAware;
-import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.scheduling.TaskScheduler;
@@ -57,7 +58,7 @@ import org.springframework.util.StringValueResolver;
*
Auto-detects any {@link SchedulingConfigurer} instances in the container,
* allowing for customization of the scheduler to be used or for fine-grained control
* over task registration (e.g. registration of {@link Trigger} tasks.
- * See @{@link EnableScheduling} Javadoc for complete usage details.
+ * See the @{@link EnableScheduling} javadocs for complete usage details.
*
* @author Mark Fisher
* @author Juergen Hoeller
@@ -70,18 +71,23 @@ import org.springframework.util.StringValueResolver;
* @see org.springframework.scheduling.config.ScheduledTaskRegistrar
*/
public class ScheduledAnnotationBeanPostProcessor
- implements BeanPostProcessor, Ordered, EmbeddedValueResolverAware, ApplicationContextAware,
- ApplicationListener, DisposableBean {
+ implements BeanPostProcessor, Ordered, EmbeddedValueResolverAware, BeanFactoryAware,
+ SmartInitializingSingleton, DisposableBean {
private Object scheduler;
private StringValueResolver embeddedValueResolver;
- private ApplicationContext applicationContext;
+ private ListableBeanFactory beanFactory;
private final ScheduledTaskRegistrar registrar = new ScheduledTaskRegistrar();
+ @Override
+ public int getOrder() {
+ return LOWEST_PRECEDENCE;
+ }
+
/**
* Set the {@link org.springframework.scheduling.TaskScheduler} that will invoke
* the scheduled methods, or a {@link java.util.concurrent.ScheduledExecutorService}
@@ -96,16 +102,63 @@ public class ScheduledAnnotationBeanPostProcessor
this.embeddedValueResolver = resolver;
}
+ /**
+ * Making a {@link BeanFactory} available is optional; if not set,
+ * {@link SchedulingConfigurer} beans won't get autodetected and
+ * a {@link #setScheduler scheduler} has to be explicitly configured.
+ */
@Override
- public void setApplicationContext(ApplicationContext applicationContext) {
- this.applicationContext = applicationContext;
+ public void setBeanFactory(BeanFactory beanFactory) {
+ this.beanFactory = (beanFactory instanceof ListableBeanFactory ? (ListableBeanFactory) beanFactory : null);
}
- @Override
- public int getOrder() {
- return LOWEST_PRECEDENCE;
+ /**
+ * @deprecated as of Spring 4.1, in favor of {@link #setBeanFactory}
+ */
+ @Deprecated
+ public void setApplicationContext(ApplicationContext applicationContext) {
+ this.beanFactory = applicationContext;
}
+
+ @Override
+ public void afterSingletonsInstantiated() {
+ if (this.scheduler != null) {
+ this.registrar.setScheduler(this.scheduler);
+ }
+
+ if (this.beanFactory != null) {
+ Map configurers = this.beanFactory.getBeansOfType(SchedulingConfigurer.class);
+ for (SchedulingConfigurer configurer : configurers.values()) {
+ configurer.configureTasks(this.registrar);
+ }
+ }
+
+ if (this.registrar.hasTasks() && this.registrar.getScheduler() == null) {
+ Assert.state(this.beanFactory != null, "BeanFactory must be set to find scheduler by type");
+ Map schedulers = new HashMap();
+ schedulers.putAll(this.beanFactory.getBeansOfType(TaskScheduler.class));
+ schedulers.putAll(this.beanFactory.getBeansOfType(ScheduledExecutorService.class));
+ if (schedulers.size() == 0) {
+ // do nothing -> fall back to default scheduler
+ }
+ else if (schedulers.size() == 1) {
+ this.registrar.setScheduler(schedulers.values().iterator().next());
+ }
+ else if (schedulers.size() >= 2){
+ throw new IllegalStateException(
+ "More than one TaskScheduler and/or ScheduledExecutorService " +
+ "exist within the context. Remove all but one of the beans; or " +
+ "implement the SchedulingConfigurer interface and call " +
+ "ScheduledTaskRegistrar#setScheduler explicitly within the " +
+ "configureTasks() callback. Found the following beans: " + schedulers.keySet());
+ }
+ }
+
+ this.registrar.afterPropertiesSet();
+ }
+
+
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
return bean;
@@ -254,44 +307,6 @@ public class ScheduledAnnotationBeanPostProcessor
}
}
- @Override
- public void onApplicationEvent(ContextRefreshedEvent event) {
- if (event.getApplicationContext() != this.applicationContext) {
- return;
- }
-
- if (this.scheduler != null) {
- this.registrar.setScheduler(this.scheduler);
- }
-
- Map configurers =
- this.applicationContext.getBeansOfType(SchedulingConfigurer.class);
- for (SchedulingConfigurer configurer : configurers.values()) {
- configurer.configureTasks(this.registrar);
- }
-
- if (this.registrar.hasTasks() && this.registrar.getScheduler() == null) {
- Map schedulers = new HashMap();
- schedulers.putAll(this.applicationContext.getBeansOfType(TaskScheduler.class));
- schedulers.putAll(this.applicationContext.getBeansOfType(ScheduledExecutorService.class));
- if (schedulers.size() == 0) {
- // do nothing -> fall back to default scheduler
- }
- else if (schedulers.size() == 1) {
- this.registrar.setScheduler(schedulers.values().iterator().next());
- }
- else if (schedulers.size() >= 2){
- throw new IllegalStateException(
- "More than one TaskScheduler and/or ScheduledExecutorService " +
- "exist within the context. Remove all but one of the beans; or " +
- "implement the SchedulingConfigurer interface and call " +
- "ScheduledTaskRegistrar#setScheduler explicitly within the " +
- "configureTasks() callback. Found the following beans: " + schedulers.keySet());
- }
- }
-
- this.registrar.afterPropertiesSet();
- }
@Override
public void destroy() {
diff --git a/spring-jms/src/main/java/org/springframework/jms/annotation/JmsListenerAnnotationBeanPostProcessor.java b/spring-jms/src/main/java/org/springframework/jms/annotation/JmsListenerAnnotationBeanPostProcessor.java
index 187f1fb5de6..fb4f49ebff4 100644
--- a/spring-jms/src/main/java/org/springframework/jms/annotation/JmsListenerAnnotationBeanPostProcessor.java
+++ b/spring-jms/src/main/java/org/springframework/jms/annotation/JmsListenerAnnotationBeanPostProcessor.java
@@ -22,14 +22,14 @@ import java.util.concurrent.atomic.AtomicInteger;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.BeanFactory;
+import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanInitializationException;
+import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
+import org.springframework.beans.factory.SmartInitializingSingleton;
import org.springframework.beans.factory.config.BeanPostProcessor;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.ApplicationContextAware;
-import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.AnnotationConfigUtils;
-import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.jms.config.DefaultJmsHandlerMethodFactory;
@@ -39,6 +39,7 @@ import org.springframework.jms.config.JmsListenerEndpointRegistrar;
import org.springframework.jms.config.JmsListenerEndpointRegistry;
import org.springframework.jms.config.MethodJmsListenerEndpoint;
import org.springframework.messaging.handler.invocation.InvocableHandlerMethod;
+import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;
@@ -60,6 +61,7 @@ import org.springframework.util.StringUtils;
* {@link EnableJms} Javadoc for complete usage details.
*
* @author Stephane Nicoll
+ * @author Juergen Hoeller
* @since 4.1
* @see JmsListener
* @see EnableJms
@@ -69,11 +71,11 @@ import org.springframework.util.StringUtils;
* @see org.springframework.jms.config.AbstractJmsListenerEndpoint
* @see MethodJmsListenerEndpoint
*/
-public class JmsListenerAnnotationBeanPostProcessor implements BeanPostProcessor, Ordered,
- ApplicationContextAware, ApplicationListener {
+public class JmsListenerAnnotationBeanPostProcessor
+ implements BeanPostProcessor, Ordered, BeanFactoryAware, SmartInitializingSingleton {
/**
- * The bean name of the default {@link JmsListenerContainerFactory}
+ * The bean name of the default {@link JmsListenerContainerFactory}.
*/
static final String DEFAULT_JMS_LISTENER_CONTAINER_FACTORY_BEAN_NAME = "jmsListenerContainerFactory";
@@ -82,9 +84,9 @@ public class JmsListenerAnnotationBeanPostProcessor implements BeanPostProcessor
private String containerFactoryBeanName = DEFAULT_JMS_LISTENER_CONTAINER_FACTORY_BEAN_NAME;
- private final JmsHandlerMethodFactoryAdapter jmsHandlerMethodFactory = new JmsHandlerMethodFactoryAdapter();
+ private BeanFactory beanFactory;
- private ApplicationContext applicationContext;
+ private final JmsHandlerMethodFactoryAdapter jmsHandlerMethodFactory = new JmsHandlerMethodFactoryAdapter();
private final JmsListenerEndpointRegistrar registrar = new JmsListenerEndpointRegistrar();
@@ -124,9 +126,50 @@ public class JmsListenerAnnotationBeanPostProcessor implements BeanPostProcessor
this.jmsHandlerMethodFactory.setJmsHandlerMethodFactory(jmsHandlerMethodFactory);
}
+ /**
+ * Making a {@link BeanFactory} available is optional; if not set,
+ * {@link JmsListenerConfigurer} beans won't get autodetected and an
+ * {@link #setEndpointRegistry endpoint registry} has to be explicitly configured.
+ */
@Override
- public void setApplicationContext(ApplicationContext applicationContext) {
- this.applicationContext = applicationContext;
+ public void setBeanFactory(BeanFactory beanFactory) {
+ this.beanFactory = beanFactory;
+ }
+
+
+ @Override
+ public void afterSingletonsInstantiated() {
+ this.registrar.setBeanFactory(this.beanFactory);
+
+ if (this.beanFactory instanceof ListableBeanFactory) {
+ Map instances =
+ ((ListableBeanFactory) this.beanFactory).getBeansOfType(JmsListenerConfigurer.class);
+ for (JmsListenerConfigurer configurer : instances.values()) {
+ configurer.configureJmsListeners(this.registrar);
+ }
+ }
+
+ if (this.registrar.getEndpointRegistry() == null) {
+ if (this.endpointRegistry == null) {
+ Assert.state(this.beanFactory != null, "BeanFactory must be set to find endpoint registry by bean name");
+ this.endpointRegistry = this.beanFactory.getBean(
+ AnnotationConfigUtils.JMS_LISTENER_ENDPOINT_REGISTRY_BEAN_NAME, JmsListenerEndpointRegistry.class);
+ }
+ this.registrar.setEndpointRegistry(this.endpointRegistry);
+ }
+
+ if (this.containerFactoryBeanName != null) {
+ this.registrar.setContainerFactoryBeanName(this.containerFactoryBeanName);
+ }
+
+ // Set the custom handler method factory once resolved by the configurer
+ JmsHandlerMethodFactory handlerMethodFactory = this.registrar.getJmsHandlerMethodFactory();
+ if (handlerMethodFactory != null) {
+ this.jmsHandlerMethodFactory.setJmsHandlerMethodFactory(handlerMethodFactory);
+ }
+
+ // Actually register all listeners
+ this.registrar.afterPropertiesSet();
}
@@ -189,8 +232,9 @@ public class JmsListenerAnnotationBeanPostProcessor implements BeanPostProcessor
JmsListenerContainerFactory> factory = null;
String containerFactoryBeanName = jmsListener.containerFactory();
if (StringUtils.hasText(containerFactoryBeanName)) {
+ Assert.state(this.beanFactory != null, "BeanFactory must be set to obtain container factory by bean name");
try {
- factory = this.applicationContext.getBean(containerFactoryBeanName, JmsListenerContainerFactory.class);
+ factory = this.beanFactory.getBean(containerFactoryBeanName, JmsListenerContainerFactory.class);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanInitializationException("Could not register jms listener endpoint on [" +
@@ -199,49 +243,7 @@ public class JmsListenerAnnotationBeanPostProcessor implements BeanPostProcessor
}
}
- registrar.registerEndpoint(endpoint, factory);
-
- }
-
- @Override
- public void onApplicationEvent(ContextRefreshedEvent event) {
- if (event.getApplicationContext() != this.applicationContext) {
- return;
- }
-
- Map instances =
- this.applicationContext.getBeansOfType(JmsListenerConfigurer.class);
- for (JmsListenerConfigurer configurer : instances.values()) {
- configurer.configureJmsListeners(registrar);
- }
-
- this.registrar.setApplicationContext(this.applicationContext);
-
- if (this.registrar.getEndpointRegistry() == null) {
- if (this.endpointRegistry == null) {
- this.endpointRegistry = this.applicationContext.getBean(
- AnnotationConfigUtils.JMS_LISTENER_ENDPOINT_REGISTRY_BEAN_NAME, JmsListenerEndpointRegistry.class);
- }
- this.registrar.setEndpointRegistry(this.endpointRegistry);
- }
-
- if (this.containerFactoryBeanName != null) {
- this.registrar.setContainerFactoryBeanName(this.containerFactoryBeanName);
- }
-
- // Set the custom handler method factory once resolved by the configurer
- JmsHandlerMethodFactory handlerMethodFactory = registrar.getJmsHandlerMethodFactory();
- if (handlerMethodFactory != null) {
- this.jmsHandlerMethodFactory.setJmsHandlerMethodFactory(handlerMethodFactory);
- }
-
- // Create all the listeners and starts them
- try {
- this.registrar.afterPropertiesSet();
- }
- catch (Exception ex) {
- throw new BeanInitializationException("Failed to initialize JmsListenerEndpointRegistrar", ex);
- }
+ this.registrar.registerEndpoint(endpoint, factory);
}
private String getEndpointId(JmsListener jmsListener) {
@@ -282,7 +284,7 @@ public class JmsListenerAnnotationBeanPostProcessor implements BeanPostProcessor
private JmsHandlerMethodFactory createDefaultJmsHandlerMethodFactory() {
DefaultJmsHandlerMethodFactory defaultFactory = new DefaultJmsHandlerMethodFactory();
- defaultFactory.setApplicationContext(applicationContext);
+ defaultFactory.setBeanFactory(beanFactory);
defaultFactory.afterPropertiesSet();
return defaultFactory;
}
diff --git a/spring-jms/src/main/java/org/springframework/jms/config/DefaultJmsHandlerMethodFactory.java b/spring-jms/src/main/java/org/springframework/jms/config/DefaultJmsHandlerMethodFactory.java
index 5b4f165c5f5..4f0f9d0f20b 100644
--- a/spring-jms/src/main/java/org/springframework/jms/config/DefaultJmsHandlerMethodFactory.java
+++ b/spring-jms/src/main/java/org/springframework/jms/config/DefaultJmsHandlerMethodFactory.java
@@ -20,11 +20,10 @@ import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
+import org.springframework.beans.factory.BeanFactory;
+import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.ApplicationContextAware;
-import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.convert.ConversionService;
import org.springframework.format.support.DefaultFormattingConversionService;
import org.springframework.messaging.converter.GenericMessageConverter;
@@ -36,8 +35,6 @@ import org.springframework.messaging.handler.annotation.support.PayloadArgumentR
import org.springframework.messaging.handler.invocation.HandlerMethodArgumentResolver;
import org.springframework.messaging.handler.invocation.HandlerMethodArgumentResolverComposite;
import org.springframework.messaging.handler.invocation.InvocableHandlerMethod;
-import org.springframework.util.Assert;
-import org.springframework.util.ClassUtils;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
@@ -57,15 +54,13 @@ import org.springframework.validation.Validator;
* can be converted
*
* @author Stephane Nicoll
+ * @author Juergen Hoeller
* @since 4.1
- * @see #setCustomArgumentResolvers(java.util.List)
- * @see #setValidator(Validator)
- * @see #setConversionService(ConversionService)
+ * @see #setConversionService
+ * @see #setValidator
+ * @see #setCustomArgumentResolvers
*/
-public class DefaultJmsHandlerMethodFactory
- implements JmsHandlerMethodFactory, InitializingBean, ApplicationContextAware {
-
- private ApplicationContext applicationContext;
+public class DefaultJmsHandlerMethodFactory implements JmsHandlerMethodFactory, BeanFactoryAware, InitializingBean {
private ConversionService conversionService = new DefaultFormattingConversionService();
@@ -73,22 +68,17 @@ public class DefaultJmsHandlerMethodFactory
private Validator validator = new NoOpValidator();
- private List customArgumentResolvers
- = new ArrayList();
+ private List customArgumentResolvers;
- private HandlerMethodArgumentResolverComposite argumentResolvers
- = new HandlerMethodArgumentResolverComposite();
+ private final HandlerMethodArgumentResolverComposite argumentResolvers =
+ new HandlerMethodArgumentResolverComposite();
+ private BeanFactory beanFactory;
- @Override
- public void setApplicationContext(ApplicationContext applicationContext) {
- this.applicationContext = applicationContext;
- }
/**
* Set the {@link ConversionService} to use to convert the original
* message payload or headers.
- *
* @see HeaderMethodArgumentResolver
* @see GenericMessageConverter
*/
@@ -96,24 +86,15 @@ public class DefaultJmsHandlerMethodFactory
this.conversionService = conversionService;
}
- protected ConversionService getConversionService() {
- return conversionService;
- }
-
/**
* Set the {@link MessageConverter} to use. By default a {@link GenericMessageConverter}
* is used.
- *
* @see GenericMessageConverter
*/
public void setMessageConverter(MessageConverter messageConverter) {
this.messageConverter = messageConverter;
}
- protected MessageConverter getMessageConverter() {
- return messageConverter;
- }
-
/**
* Set the Validator instance used for validating @Payload arguments
* @see org.springframework.validation.annotation.Validated
@@ -123,27 +104,15 @@ public class DefaultJmsHandlerMethodFactory
this.validator = validator;
}
- /**
- * The configured Validator instance
- */
- public Validator getValidator() {
- return validator;
- }
-
/**
* Set the list of custom {@code HandlerMethodArgumentResolver}s that will be used
* after resolvers for supported argument type.
- * @param customArgumentResolvers the list of resolvers; never {@code null}.
+ * @param customArgumentResolvers the list of resolvers (never {@code null})
*/
public void setCustomArgumentResolvers(List customArgumentResolvers) {
- Assert.notNull(customArgumentResolvers, "The 'customArgumentResolvers' cannot be null.");
this.customArgumentResolvers = customArgumentResolvers;
}
- public List getCustomArgumentResolvers() {
- return customArgumentResolvers;
- }
-
/**
* Configure the complete list of supported argument types effectively overriding
* the ones configured by default. This is an advanced option. For most use cases
@@ -157,20 +126,26 @@ public class DefaultJmsHandlerMethodFactory
this.argumentResolvers.addResolvers(argumentResolvers);
}
- public List getArgumentResolvers() {
- return this.argumentResolvers.getResolvers();
+ /**
+ * A {@link BeanFactory} only needs to be available for placeholder resolution
+ * in handler method arguments; it's optional otherwise.
+ */
+ @Override
+ public void setBeanFactory(BeanFactory beanFactory) {
+ this.beanFactory = beanFactory;
}
@Override
public void afterPropertiesSet() {
- if (messageConverter == null) {
- messageConverter = new GenericMessageConverter(getConversionService());
+ if (this.messageConverter == null) {
+ this.messageConverter = new GenericMessageConverter(this.conversionService);
}
if (this.argumentResolvers.getResolvers().isEmpty()) {
this.argumentResolvers.addResolvers(initArgumentResolvers());
}
}
+
@Override
public InvocableHandlerMethod createInvocableHandlerMethod(Object bean, Method method) {
InvocableHandlerMethod handlerMethod = new InvocableHandlerMethod(bean, method);
@@ -179,27 +154,28 @@ public class DefaultJmsHandlerMethodFactory
}
protected List initArgumentResolvers() {
- ConfigurableBeanFactory beanFactory =
- (ClassUtils.isAssignableValue(ConfigurableApplicationContext.class, applicationContext)) ?
- ((ConfigurableApplicationContext) applicationContext).getBeanFactory() : null;
-
List resolvers = new ArrayList();
+ ConfigurableBeanFactory cbf = (this.beanFactory instanceof ConfigurableBeanFactory ?
+ (ConfigurableBeanFactory) this.beanFactory : null);
// Annotation-based argument resolution
- resolvers.add(new HeaderMethodArgumentResolver(getConversionService(), beanFactory));
+ resolvers.add(new HeaderMethodArgumentResolver(this.conversionService, cbf));
resolvers.add(new HeadersMethodArgumentResolver());
// Type-based argument resolution
resolvers.add(new MessageMethodArgumentResolver());
- resolvers.addAll(getCustomArgumentResolvers());
- resolvers.add(new PayloadArgumentResolver(getMessageConverter(), getValidator()));
+ if (this.customArgumentResolvers != null) {
+ resolvers.addAll(this.customArgumentResolvers);
+ }
+ resolvers.add(new PayloadArgumentResolver(this.messageConverter, this.validator));
return resolvers;
}
private static final class NoOpValidator implements Validator {
+
@Override
public boolean supports(Class> clazz) {
return false;
diff --git a/spring-jms/src/main/java/org/springframework/jms/config/JmsListenerEndpointRegistrar.java b/spring-jms/src/main/java/org/springframework/jms/config/JmsListenerEndpointRegistrar.java
index 75f24e02dd2..df1d0279135 100644
--- a/spring-jms/src/main/java/org/springframework/jms/config/JmsListenerEndpointRegistrar.java
+++ b/spring-jms/src/main/java/org/springframework/jms/config/JmsListenerEndpointRegistrar.java
@@ -19,9 +19,9 @@ package org.springframework.jms.config;
import java.util.ArrayList;
import java.util.List;
+import org.springframework.beans.factory.BeanFactory;
+import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.InitializingBean;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.ApplicationContextAware;
import org.springframework.util.Assert;
/**
@@ -29,24 +29,26 @@ import org.springframework.util.Assert;
* a {@link JmsListenerEndpointRegistry}.
*
* @author Stephane Nicoll
+ * @author Juergen Hoeller
* @since 4.1
* @see org.springframework.jms.annotation.JmsListenerConfigurer
*/
-public class JmsListenerEndpointRegistrar implements ApplicationContextAware, InitializingBean {
+public class JmsListenerEndpointRegistrar implements BeanFactoryAware, InitializingBean {
private JmsListenerEndpointRegistry endpointRegistry;
- private String containerFactoryBeanName;
+ private JmsHandlerMethodFactory jmsHandlerMethodFactory;
private JmsListenerContainerFactory> containerFactory;
- private JmsHandlerMethodFactory jmsHandlerMethodFactory;
+ private String containerFactoryBeanName;
- private ApplicationContext applicationContext;
+ private BeanFactory beanFactory;
private final List endpointDescriptors =
new ArrayList();
+
/**
* Set the {@link JmsListenerEndpointRegistry} instance to use.
*/
@@ -59,27 +61,7 @@ public class JmsListenerEndpointRegistrar implements ApplicationContextAware, In
* registrar, may be {@code null}.
*/
public JmsListenerEndpointRegistry getEndpointRegistry() {
- return endpointRegistry;
- }
-
- /**
- * Set the bean name of the {@link JmsListenerContainerFactory} to use in
- * case a {@link JmsListenerEndpoint} is registered with a {@code null}
- * container factory. Alternatively, the container factory instance can
- * be registered directly, see {@link #setContainerFactory(JmsListenerContainerFactory)}
- */
- public void setContainerFactoryBeanName(String containerFactoryBeanName) {
- this.containerFactoryBeanName = containerFactoryBeanName;
- }
-
- /**
- * Set the {@link JmsListenerContainerFactory} to use in case a {@link JmsListenerEndpoint}
- * is registered with a {@code null} container factory.
- * Alternatively, the bean name of the {@link JmsListenerContainerFactory} to use
- * can be specified for a lazy lookup, see {@link #setContainerFactoryBeanName}.
- */
- public void setContainerFactory(JmsListenerContainerFactory> containerFactory) {
- this.containerFactory = containerFactory;
+ return this.endpointRegistry;
}
/**
@@ -98,12 +80,69 @@ public class JmsListenerEndpointRegistrar implements ApplicationContextAware, In
* Return the custom {@link JmsHandlerMethodFactory} to use, if any.
*/
public JmsHandlerMethodFactory getJmsHandlerMethodFactory() {
- return jmsHandlerMethodFactory;
+ return this.jmsHandlerMethodFactory;
}
+ /**
+ * Set the {@link JmsListenerContainerFactory} to use in case a {@link JmsListenerEndpoint}
+ * is registered with a {@code null} container factory.
+ *
Alternatively, the bean name of the {@link JmsListenerContainerFactory} to use
+ * can be specified for a lazy lookup, see {@link #setContainerFactoryBeanName}.
+ */
+ public void setContainerFactory(JmsListenerContainerFactory> containerFactory) {
+ this.containerFactory = containerFactory;
+ }
+
+ /**
+ * Set the bean name of the {@link JmsListenerContainerFactory} to use in case
+ * a {@link JmsListenerEndpoint} is registered with a {@code null} container factory.
+ * Alternatively, the container factory instance can be registered directly:
+ * see {@link #setContainerFactory(JmsListenerContainerFactory)}.
+ * @see #setBeanFactory
+ */
+ public void setContainerFactoryBeanName(String containerFactoryBeanName) {
+ this.containerFactoryBeanName = containerFactoryBeanName;
+ }
+
+ /**
+ * A {@link BeanFactory} only needs to be available in conjunction with
+ * {@link #setContainerFactoryBeanName}.
+ */
@Override
- public void setApplicationContext(ApplicationContext applicationContext) {
- this.applicationContext = applicationContext;
+ public void setBeanFactory(BeanFactory beanFactory) {
+ this.beanFactory = beanFactory;
+ }
+
+
+ @Override
+ public void afterPropertiesSet() {
+ registerAllEndpoints();
+ }
+
+ protected void registerAllEndpoints() {
+ for (JmsListenerEndpointDescriptor descriptor : this.endpointDescriptors) {
+ this.endpointRegistry.registerListenerContainer(descriptor.endpoint, resolveContainerFactory(descriptor));
+ }
+ }
+
+ private JmsListenerContainerFactory> resolveContainerFactory(JmsListenerEndpointDescriptor descriptor) {
+ if (descriptor.containerFactory != null) {
+ return descriptor.containerFactory;
+ }
+ else if (this.containerFactory != null) {
+ return this.containerFactory;
+ }
+ else if (this.containerFactoryBeanName != null) {
+ Assert.state(this.beanFactory != null, "BeanFactory must be set to obtain container factory by bean name");
+ this.containerFactory = this.beanFactory.getBean(
+ this.containerFactoryBeanName, JmsListenerContainerFactory.class);
+ return this.containerFactory; // Consider changing this if live change of the factory is required
+ }
+ else {
+ throw new IllegalStateException("Could not resolve the " +
+ JmsListenerContainerFactory.class.getSimpleName() + " to use for [" +
+ descriptor.endpoint + "] no factory was given and no default is set.");
+ }
}
/**
@@ -129,38 +168,6 @@ public class JmsListenerEndpointRegistrar implements ApplicationContextAware, In
registerEndpoint(endpoint, null);
}
- @Override
- public void afterPropertiesSet() throws Exception {
- Assert.notNull(applicationContext, "ApplicationContext must not be null");
- startAllEndpoints();
- }
-
- protected void startAllEndpoints() throws Exception {
- for (JmsListenerEndpointDescriptor descriptor : endpointDescriptors) {
- endpointRegistry.registerListenerContainer(
- descriptor.endpoint, resolveContainerFactory(descriptor));
- }
- }
-
- private JmsListenerContainerFactory> resolveContainerFactory(JmsListenerEndpointDescriptor descriptor) {
- if (descriptor.containerFactory != null) {
- return descriptor.containerFactory;
- }
- else if (this.containerFactory != null) {
- return this.containerFactory;
- }
- else if (this.containerFactoryBeanName != null) {
- this.containerFactory = this.applicationContext.getBean(
- this.containerFactoryBeanName, JmsListenerContainerFactory.class);
- return this.containerFactory; // Consider changing this if live change of the factory is required
- }
- else {
- throw new IllegalStateException("Could not resolve the " +
- JmsListenerContainerFactory.class.getSimpleName() + " to use for [" +
- descriptor.endpoint + "] no factory was given and no default is set.");
- }
- }
-
private static class JmsListenerEndpointDescriptor {
diff --git a/spring-jms/src/test/java/org/springframework/jms/annotation/JmsListenerAnnotationBeanPostProcessorTests.java b/spring-jms/src/test/java/org/springframework/jms/annotation/JmsListenerAnnotationBeanPostProcessorTests.java
index ec9a3565aa1..fe96e08b826 100644
--- a/spring-jms/src/test/java/org/springframework/jms/annotation/JmsListenerAnnotationBeanPostProcessorTests.java
+++ b/spring-jms/src/test/java/org/springframework/jms/annotation/JmsListenerAnnotationBeanPostProcessorTests.java
@@ -40,6 +40,7 @@ import static org.junit.Assert.*;
/**
* @author Stephane Nicoll
+ * @author Juergen Hoeller
*/
public class JmsListenerAnnotationBeanPostProcessorTests {
@@ -62,9 +63,7 @@ public class JmsListenerAnnotationBeanPostProcessorTests {
methodEndpoint.setupListenerContainer(listenerContainer);
assertNotNull(listenerContainer.getMessageListener());
- context.start();
assertTrue("Should have been started " + container, container.isStarted());
-
context.close(); // Close and stop the listeners
assertTrue("Should have been stopped " + container, container.isStopped());
}
diff --git a/spring-jms/src/test/java/org/springframework/jms/config/DefaultJmsHandlerMethodFactoryTests.java b/spring-jms/src/test/java/org/springframework/jms/config/DefaultJmsHandlerMethodFactoryTests.java
index 0e9cd9cdcbb..5ea4d98bd7b 100644
--- a/spring-jms/src/test/java/org/springframework/jms/config/DefaultJmsHandlerMethodFactoryTests.java
+++ b/spring-jms/src/test/java/org/springframework/jms/config/DefaultJmsHandlerMethodFactoryTests.java
@@ -16,8 +16,6 @@
package org.springframework.jms.config;
-import static org.junit.Assert.*;
-
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
@@ -31,7 +29,7 @@ import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.TestName;
-import org.springframework.context.support.StaticApplicationContext;
+import org.springframework.beans.factory.support.StaticListableBeanFactory;
import org.springframework.core.MethodParameter;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.support.GenericConversionService;
@@ -44,8 +42,9 @@ import org.springframework.messaging.handler.invocation.InvocableHandlerMethod;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.util.ReflectionUtils;
+import static org.junit.Assert.*;
+
/**
- *
* @author Stephane Nicoll
*/
public class DefaultJmsHandlerMethodFactoryTests {
@@ -160,15 +159,13 @@ public class DefaultJmsHandlerMethodFactoryTests {
private DefaultJmsHandlerMethodFactory createInstance() {
DefaultJmsHandlerMethodFactory factory = new DefaultJmsHandlerMethodFactory();
- factory.setApplicationContext(new StaticApplicationContext());
+ factory.setBeanFactory(new StaticListableBeanFactory());
return factory;
}
private Method getListenerMethod(String methodName, Class>... parameterTypes) {
- Method method = ReflectionUtils.findMethod(SampleBean.class,
- methodName, parameterTypes);
- assertNotNull("no method found with name " + methodName
- + " and parameters " + Arrays.toString(parameterTypes));
+ Method method = ReflectionUtils.findMethod(SampleBean.class, methodName, parameterTypes);
+ assertNotNull("no method found with name " + methodName + " and parameters " + Arrays.toString(parameterTypes));
return method;
}
@@ -187,6 +184,7 @@ public class DefaultJmsHandlerMethodFactoryTests {
}
}
+
static class CustomHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {
@Override
diff --git a/spring-jms/src/test/java/org/springframework/jms/config/JmsListenerContainerFactoryIntegrationTests.java b/spring-jms/src/test/java/org/springframework/jms/config/JmsListenerContainerFactoryIntegrationTests.java
index 77a6585ec06..198b37af15d 100644
--- a/spring-jms/src/test/java/org/springframework/jms/config/JmsListenerContainerFactoryIntegrationTests.java
+++ b/spring-jms/src/test/java/org/springframework/jms/config/JmsListenerContainerFactoryIntegrationTests.java
@@ -16,14 +16,10 @@
package org.springframework.jms.config;
-import static org.junit.Assert.*;
-import static org.mockito.Mockito.*;
-
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
-
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
@@ -33,7 +29,7 @@ import javax.jms.TextMessage;
import org.junit.Before;
import org.junit.Test;
-import org.springframework.context.support.StaticApplicationContext;
+import org.springframework.beans.factory.support.StaticListableBeanFactory;
import org.springframework.jms.StubTextMessage;
import org.springframework.jms.listener.DefaultMessageListenerContainer;
import org.springframework.jms.listener.SessionAwareMessageListener;
@@ -42,8 +38,10 @@ import org.springframework.jms.support.converter.MessageConverter;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.util.ReflectionUtils;
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.*;
+
/**
- *
* @author Stephane Nicoll
*/
public class JmsListenerContainerFactoryIntegrationTests {
@@ -54,6 +52,7 @@ public class JmsListenerContainerFactoryIntegrationTests {
private final JmsEndpointSampleBean sample = new JmsEndpointSampleBean();
+
@Before
public void setup() {
initializeFactory(factory);
@@ -70,16 +69,6 @@ public class JmsListenerContainerFactoryIntegrationTests {
assertListenerMethodInvocation("expectFooBarUpperCase");
}
- static class JmsEndpointSampleBean {
-
- private final Map invocations = new HashMap();
-
- public void expectFooBarUpperCase(@Payload String msg) {
- invocations.put("expectFooBarUpperCase", true);
- assertEquals("Unexpected payload message", "FOO-BAR", msg);
- }
- }
-
@SuppressWarnings("unchecked")
private void invokeListener(JmsListenerEndpoint endpoint, Message message) throws JMSException {
DefaultMessageListenerContainer messageListenerContainer =
@@ -112,21 +101,31 @@ public class JmsListenerContainerFactoryIntegrationTests {
}
private Method getListenerMethod(String methodName, Class>... parameterTypes) {
- Method method = ReflectionUtils.findMethod(JmsEndpointSampleBean.class,
- methodName, parameterTypes);
- assertNotNull("no method found with name " + methodName
- + " and parameters " + Arrays.toString(parameterTypes));
+ Method method = ReflectionUtils.findMethod(JmsEndpointSampleBean.class, methodName, parameterTypes);
+ assertNotNull("no method found with name " + methodName + " and parameters " + Arrays.toString(parameterTypes));
return method;
}
private void initializeFactory(DefaultJmsHandlerMethodFactory factory) {
- factory.setApplicationContext(new StaticApplicationContext());
+ factory.setBeanFactory(new StaticListableBeanFactory());
factory.afterPropertiesSet();
}
+ static class JmsEndpointSampleBean {
+
+ private final Map invocations = new HashMap();
+
+ public void expectFooBarUpperCase(@Payload String msg) {
+ invocations.put("expectFooBarUpperCase", true);
+ assertEquals("Unexpected payload message", "FOO-BAR", msg);
+ }
+ }
+
+
private static class UpperCaseMessageConverter implements MessageConverter {
+
@Override
public Message toMessage(Object object, Session session) throws JMSException, MessageConversionException {
return new StubTextMessage(object.toString().toUpperCase());
@@ -138,6 +137,5 @@ public class JmsListenerContainerFactoryIntegrationTests {
return content.toUpperCase();
}
}
+
}
-
-
diff --git a/spring-jms/src/test/java/org/springframework/jms/config/JmsListenerEndpointRegistrarTests.java b/spring-jms/src/test/java/org/springframework/jms/config/JmsListenerEndpointRegistrarTests.java
index aae03c2d106..b0fde624002 100644
--- a/spring-jms/src/test/java/org/springframework/jms/config/JmsListenerEndpointRegistrarTests.java
+++ b/spring-jms/src/test/java/org/springframework/jms/config/JmsListenerEndpointRegistrarTests.java
@@ -16,17 +16,16 @@
package org.springframework.jms.config;
-import static org.junit.Assert.*;
-
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
-import org.springframework.context.support.StaticApplicationContext;
+import org.springframework.beans.factory.support.StaticListableBeanFactory;
+
+import static org.junit.Assert.*;
/**
- *
* @author Stephane Nicoll
*/
public class JmsListenerEndpointRegistrarTests {
@@ -40,10 +39,11 @@ public class JmsListenerEndpointRegistrarTests {
private final JmsListenerContainerTestFactory containerFactory = new JmsListenerContainerTestFactory();
+
@Before
public void setup() {
registrar.setEndpointRegistry(registry);
- registrar.setApplicationContext(new StaticApplicationContext());
+ registrar.setBeanFactory(new StaticListableBeanFactory());
}
@Test
diff --git a/spring-jms/src/test/java/org/springframework/jms/config/MethodJmsListenerEndpointTests.java b/spring-jms/src/test/java/org/springframework/jms/config/MethodJmsListenerEndpointTests.java
index e4525361e82..cc73655f76f 100644
--- a/spring-jms/src/test/java/org/springframework/jms/config/MethodJmsListenerEndpointTests.java
+++ b/spring-jms/src/test/java/org/springframework/jms/config/MethodJmsListenerEndpointTests.java
@@ -16,16 +16,11 @@
package org.springframework.jms.config;
-import static org.junit.Assert.*;
-import static org.mockito.BDDMockito.given;
-import static org.mockito.Mockito.*;
-
import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
-
import javax.jms.Destination;
import javax.jms.InvalidDestinationException;
import javax.jms.JMSException;
@@ -41,16 +36,16 @@ import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.TestName;
-import org.springframework.context.support.StaticApplicationContext;
+import org.springframework.beans.factory.support.StaticListableBeanFactory;
import org.springframework.jms.StubTextMessage;
import org.springframework.jms.listener.DefaultMessageListenerContainer;
import org.springframework.jms.listener.MessageListenerContainer;
import org.springframework.jms.listener.SimpleMessageListenerContainer;
-import org.springframework.jms.listener.adapter.ReplyFailureException;
import org.springframework.jms.listener.adapter.ListenerExecutionFailedException;
import org.springframework.jms.listener.adapter.MessagingMessageListenerAdapter;
-import org.springframework.jms.support.JmsMessageHeaderAccessor;
+import org.springframework.jms.listener.adapter.ReplyFailureException;
import org.springframework.jms.support.JmsHeaders;
+import org.springframework.jms.support.JmsMessageHeaderAccessor;
import org.springframework.jms.support.destination.DestinationResolver;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHeaders;
@@ -65,8 +60,12 @@ import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
import org.springframework.validation.annotation.Validated;
+import static org.junit.Assert.*;
+import static org.mockito.BDDMockito.*;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
/**
- *
* @author Stephane Nicoll
*/
public class MethodJmsListenerEndpointTests {
@@ -83,6 +82,7 @@ public class MethodJmsListenerEndpointTests {
private final JmsEndpointSampleBean sample = new JmsEndpointSampleBean();
+
@Before
public void setup() {
initializeFactory(factory);
@@ -375,10 +375,8 @@ public class MethodJmsListenerEndpointTests {
}
private Method getListenerMethod(String methodName, Class>... parameterTypes) {
- Method method = ReflectionUtils.findMethod(JmsEndpointSampleBean.class,
- methodName, parameterTypes);
- assertNotNull("no method found with name " + methodName
- + " and parameters " + Arrays.toString(parameterTypes));
+ Method method = ReflectionUtils.findMethod(JmsEndpointSampleBean.class, methodName, parameterTypes);
+ assertNotNull("no method found with name " + methodName + " and parameters " + Arrays.toString(parameterTypes));
return method;
}
@@ -395,12 +393,11 @@ public class MethodJmsListenerEndpointTests {
}
private void initializeFactory(DefaultJmsHandlerMethodFactory factory) {
- factory.setApplicationContext(new StaticApplicationContext());
+ factory.setBeanFactory(new StaticListableBeanFactory());
factory.afterPropertiesSet();
}
private Validator testValidator(final String invalidValue) {
-
return new Validator() {
@Override
public boolean supports(Class> clazz) {
@@ -520,11 +517,11 @@ public class MethodJmsListenerEndpointTests {
}
+
@SuppressWarnings("serial")
static class MyBean implements Serializable {
private String name;
}
-
}
diff --git a/spring-jms/src/test/java/org/springframework/jms/listener/adapter/MessagingMessageListenerAdapterTests.java b/spring-jms/src/test/java/org/springframework/jms/listener/adapter/MessagingMessageListenerAdapterTests.java
index 581cc68b747..18414559011 100644
--- a/spring-jms/src/test/java/org/springframework/jms/listener/adapter/MessagingMessageListenerAdapterTests.java
+++ b/spring-jms/src/test/java/org/springframework/jms/listener/adapter/MessagingMessageListenerAdapterTests.java
@@ -25,7 +25,7 @@ import javax.jms.TextMessage;
import org.junit.Before;
import org.junit.Test;
-import org.springframework.context.support.StaticApplicationContext;
+import org.springframework.beans.factory.support.StaticListableBeanFactory;
import org.springframework.jms.StubTextMessage;
import org.springframework.jms.config.DefaultJmsHandlerMethodFactory;
import org.springframework.jms.support.JmsHeaders;
@@ -38,7 +38,6 @@ import static org.junit.Assert.*;
import static org.mockito.BDDMockito.*;
/**
- *
* @author Stephane Nicoll
*/
public class MessagingMessageListenerAdapterTests {
@@ -124,7 +123,7 @@ public class MessagingMessageListenerAdapterTests {
}
private void initializeFactory(DefaultJmsHandlerMethodFactory factory) {
- factory.setApplicationContext(new StaticApplicationContext());
+ factory.setBeanFactory(new StaticListableBeanFactory());
factory.afterPropertiesSet();
}