From 8c4388dd6e7f44ff230644c4fb3bc204d0b6ff60 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Mon, 1 Sep 2014 11:12:49 +0200 Subject: [PATCH] Place holder resolution in @JmsListener arguments This commit allows to use place holder definitions for JmsListener attributes, effectively allowing to externalize those settings from the code. Issue: SPR-12134 --- ...msListenerAnnotationBeanPostProcessor.java | 25 ++++++++++++++----- .../AbstractJmsAnnotationDrivenTests.java | 17 ++++++++++++- .../AnnotationDrivenNamespaceTests.java | 7 ++++++ .../jms/annotation/EnableJmsTests.java | 25 +++++++++++++++++++ ...tation-driven-full-configurable-config.xml | 22 ++++++++++++++++ .../jms/annotation/jms-listener.properties | 6 +++++ 6 files changed, 95 insertions(+), 7 deletions(-) create mode 100644 spring-jms/src/test/resources/org/springframework/jms/annotation/annotation-driven-full-configurable-config.xml create mode 100644 spring-jms/src/test/resources/org/springframework/jms/annotation/jms-listener.properties 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 da37641be7b..ac2529c1d11 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 @@ -29,6 +29,7 @@ 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.beans.factory.config.ConfigurableBeanFactory; import org.springframework.core.Ordered; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.jms.config.JmsListenerConfigUtils; @@ -218,19 +219,19 @@ public class JmsListenerAnnotationBeanPostProcessor endpoint.setMethod(method); endpoint.setMessageHandlerMethodFactory(this.messageHandlerMethodFactory); endpoint.setId(getEndpointId(jmsListener)); - endpoint.setDestination(jmsListener.destination()); + endpoint.setDestination(resolve(jmsListener.destination())); if (StringUtils.hasText(jmsListener.selector())) { - endpoint.setSelector(jmsListener.selector()); + endpoint.setSelector(resolve(jmsListener.selector())); } if (StringUtils.hasText(jmsListener.subscription())) { - endpoint.setSubscription(jmsListener.subscription()); + endpoint.setSubscription(resolve(jmsListener.subscription())); } if (StringUtils.hasText(jmsListener.concurrency())) { - endpoint.setConcurrency(jmsListener.concurrency()); + endpoint.setConcurrency(resolve(jmsListener.concurrency())); } JmsListenerContainerFactory factory = null; - String containerFactoryBeanName = jmsListener.containerFactory(); + String containerFactoryBeanName = resolve(jmsListener.containerFactory()); if (StringUtils.hasText(containerFactoryBeanName)) { Assert.state(this.beanFactory != null, "BeanFactory must be set to obtain container factory by bean name"); try { @@ -248,13 +249,25 @@ public class JmsListenerAnnotationBeanPostProcessor private String getEndpointId(JmsListener jmsListener) { if (StringUtils.hasText(jmsListener.id())) { - return jmsListener.id(); + return resolve(jmsListener.id()); } else { return "org.springframework.jms.JmsListenerEndpointContainer#" + counter.getAndIncrement(); } } + /** + * Resolve the specified value if possible. + * + * @see ConfigurableBeanFactory#resolveEmbeddedValue + */ + private String resolve(String value) { + if (this.beanFactory != null && this.beanFactory instanceof ConfigurableBeanFactory) { + return ((ConfigurableBeanFactory) this.beanFactory).resolveEmbeddedValue(value); + } + return value; + } + /** * A {@link MessageHandlerMethodFactory} adapter that offers a configurable underlying diff --git a/spring-jms/src/test/java/org/springframework/jms/annotation/AbstractJmsAnnotationDrivenTests.java b/spring-jms/src/test/java/org/springframework/jms/annotation/AbstractJmsAnnotationDrivenTests.java index adafb27b941..27a0198f097 100644 --- a/spring-jms/src/test/java/org/springframework/jms/annotation/AbstractJmsAnnotationDrivenTests.java +++ b/spring-jms/src/test/java/org/springframework/jms/annotation/AbstractJmsAnnotationDrivenTests.java @@ -55,6 +55,9 @@ public abstract class AbstractJmsAnnotationDrivenTests { @Test public abstract void fullConfiguration(); + @Test + public abstract void fullConfigurableConfiguration(); + @Test public abstract void customConfiguration(); @@ -107,13 +110,25 @@ public abstract class AbstractJmsAnnotationDrivenTests { assertEquals("queueIn", endpoint.getDestination()); assertEquals("mySelector", endpoint.getSelector()); assertEquals("mySubscription", endpoint.getSubscription()); + assertEquals("1-10", endpoint.getConcurrency()); } @Component static class FullBean { @JmsListener(id = "listener1", containerFactory = "simpleFactory", destination = "queueIn", - selector = "mySelector", subscription = "mySubscription") + selector = "mySelector", subscription = "mySubscription", concurrency = "1-10") + public String fullHandle(String msg) { + return "reply"; + } + } + + @Component + static class FullConfigurableBean { + + @JmsListener(id = "${jms.listener.id}", containerFactory = "${jms.listener.containerFactory}", + destination = "${jms.listener.destination}", selector = "${jms.listener.selector}", + subscription = "${jms.listener.subscription}", concurrency = "${jms.listener.concurrency}") public String fullHandle(String msg) { return "reply"; } diff --git a/spring-jms/src/test/java/org/springframework/jms/annotation/AnnotationDrivenNamespaceTests.java b/spring-jms/src/test/java/org/springframework/jms/annotation/AnnotationDrivenNamespaceTests.java index a6859c31aa7..22f8a334eab 100644 --- a/spring-jms/src/test/java/org/springframework/jms/annotation/AnnotationDrivenNamespaceTests.java +++ b/spring-jms/src/test/java/org/springframework/jms/annotation/AnnotationDrivenNamespaceTests.java @@ -51,6 +51,13 @@ public class AnnotationDrivenNamespaceTests extends AbstractJmsAnnotationDrivenT testFullConfiguration(context); } + @Override + public void fullConfigurableConfiguration() { + ApplicationContext context = new ClassPathXmlApplicationContext( + "annotation-driven-full-configurable-config.xml", getClass()); + testFullConfiguration(context); + } + @Override @Test public void customConfiguration() { diff --git a/spring-jms/src/test/java/org/springframework/jms/annotation/EnableJmsTests.java b/spring-jms/src/test/java/org/springframework/jms/annotation/EnableJmsTests.java index 9394e21eac7..e39cf97b3cc 100644 --- a/spring-jms/src/test/java/org/springframework/jms/annotation/EnableJmsTests.java +++ b/spring-jms/src/test/java/org/springframework/jms/annotation/EnableJmsTests.java @@ -29,6 +29,8 @@ import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; +import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; import org.springframework.messaging.handler.annotation.support.DefaultMessageHandlerMethodFactory; import org.springframework.messaging.handler.annotation.support.MessageHandlerMethodFactory; import org.springframework.jms.config.JmsListenerContainerTestFactory; @@ -63,6 +65,13 @@ public class EnableJmsTests extends AbstractJmsAnnotationDrivenTests { testFullConfiguration(context); } + @Override + public void fullConfigurableConfiguration() { + ConfigurableApplicationContext context = new AnnotationConfigApplicationContext( + EnableJmsFullConfigurableConfig.class, FullConfigurableBean.class); + testFullConfiguration(context); + } + @Override @Test public void customConfiguration() { @@ -131,6 +140,22 @@ public class EnableJmsTests extends AbstractJmsAnnotationDrivenTests { } } + @EnableJms + @Configuration + @PropertySource("classpath:/org/springframework/jms/annotation/jms-listener.properties") + static class EnableJmsFullConfigurableConfig { + + @Bean + public JmsListenerContainerTestFactory simpleFactory() { + return new JmsListenerContainerTestFactory(); + } + + @Bean + public PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { + return new PropertySourcesPlaceholderConfigurer(); + } + } + @Configuration @EnableJms static class EnableJmsCustomConfig implements JmsListenerConfigurer { diff --git a/spring-jms/src/test/resources/org/springframework/jms/annotation/annotation-driven-full-configurable-config.xml b/spring-jms/src/test/resources/org/springframework/jms/annotation/annotation-driven-full-configurable-config.xml new file mode 100644 index 00000000000..f3ba53769c1 --- /dev/null +++ b/spring-jms/src/test/resources/org/springframework/jms/annotation/annotation-driven-full-configurable-config.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-jms/src/test/resources/org/springframework/jms/annotation/jms-listener.properties b/spring-jms/src/test/resources/org/springframework/jms/annotation/jms-listener.properties new file mode 100644 index 00000000000..18459dcffe0 --- /dev/null +++ b/spring-jms/src/test/resources/org/springframework/jms/annotation/jms-listener.properties @@ -0,0 +1,6 @@ +jms.listener.id=listener1 +jms.listener.containerFactory=simpleFactory +jms.listener.destination=queueIn +jms.listener.selector=mySelector +jms.listener.subscription=mySubscription +jms.listener.concurrency=1-10 \ No newline at end of file