Skip to content

Commit 8c4388d

Browse files
committed
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
1 parent b4a6caf commit 8c4388d

File tree

6 files changed

+95
-7
lines changed

6 files changed

+95
-7
lines changed

spring-jms/src/main/java/org/springframework/jms/annotation/JmsListenerAnnotationBeanPostProcessor.java

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
3030
import org.springframework.beans.factory.SmartInitializingSingleton;
3131
import org.springframework.beans.factory.config.BeanPostProcessor;
32+
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
3233
import org.springframework.core.Ordered;
3334
import org.springframework.core.annotation.AnnotationUtils;
3435
import org.springframework.jms.config.JmsListenerConfigUtils;
@@ -218,19 +219,19 @@ protected void processJmsListener(JmsListener jmsListener, Method method, Object
218219
endpoint.setMethod(method);
219220
endpoint.setMessageHandlerMethodFactory(this.messageHandlerMethodFactory);
220221
endpoint.setId(getEndpointId(jmsListener));
221-
endpoint.setDestination(jmsListener.destination());
222+
endpoint.setDestination(resolve(jmsListener.destination()));
222223
if (StringUtils.hasText(jmsListener.selector())) {
223-
endpoint.setSelector(jmsListener.selector());
224+
endpoint.setSelector(resolve(jmsListener.selector()));
224225
}
225226
if (StringUtils.hasText(jmsListener.subscription())) {
226-
endpoint.setSubscription(jmsListener.subscription());
227+
endpoint.setSubscription(resolve(jmsListener.subscription()));
227228
}
228229
if (StringUtils.hasText(jmsListener.concurrency())) {
229-
endpoint.setConcurrency(jmsListener.concurrency());
230+
endpoint.setConcurrency(resolve(jmsListener.concurrency()));
230231
}
231232

232233
JmsListenerContainerFactory<?> factory = null;
233-
String containerFactoryBeanName = jmsListener.containerFactory();
234+
String containerFactoryBeanName = resolve(jmsListener.containerFactory());
234235
if (StringUtils.hasText(containerFactoryBeanName)) {
235236
Assert.state(this.beanFactory != null, "BeanFactory must be set to obtain container factory by bean name");
236237
try {
@@ -248,13 +249,25 @@ protected void processJmsListener(JmsListener jmsListener, Method method, Object
248249

249250
private String getEndpointId(JmsListener jmsListener) {
250251
if (StringUtils.hasText(jmsListener.id())) {
251-
return jmsListener.id();
252+
return resolve(jmsListener.id());
252253
}
253254
else {
254255
return "org.springframework.jms.JmsListenerEndpointContainer#" + counter.getAndIncrement();
255256
}
256257
}
257258

259+
/**
260+
* Resolve the specified value if possible.
261+
*
262+
* @see ConfigurableBeanFactory#resolveEmbeddedValue
263+
*/
264+
private String resolve(String value) {
265+
if (this.beanFactory != null && this.beanFactory instanceof ConfigurableBeanFactory) {
266+
return ((ConfigurableBeanFactory) this.beanFactory).resolveEmbeddedValue(value);
267+
}
268+
return value;
269+
}
270+
258271

259272
/**
260273
* A {@link MessageHandlerMethodFactory} adapter that offers a configurable underlying

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

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ public abstract class AbstractJmsAnnotationDrivenTests {
5555
@Test
5656
public abstract void fullConfiguration();
5757

58+
@Test
59+
public abstract void fullConfigurableConfiguration();
60+
5861
@Test
5962
public abstract void customConfiguration();
6063

@@ -107,13 +110,25 @@ public void testFullConfiguration(ApplicationContext context) {
107110
assertEquals("queueIn", endpoint.getDestination());
108111
assertEquals("mySelector", endpoint.getSelector());
109112
assertEquals("mySubscription", endpoint.getSubscription());
113+
assertEquals("1-10", endpoint.getConcurrency());
110114
}
111115

112116
@Component
113117
static class FullBean {
114118

115119
@JmsListener(id = "listener1", containerFactory = "simpleFactory", destination = "queueIn",
116-
selector = "mySelector", subscription = "mySubscription")
120+
selector = "mySelector", subscription = "mySubscription", concurrency = "1-10")
121+
public String fullHandle(String msg) {
122+
return "reply";
123+
}
124+
}
125+
126+
@Component
127+
static class FullConfigurableBean {
128+
129+
@JmsListener(id = "${jms.listener.id}", containerFactory = "${jms.listener.containerFactory}",
130+
destination = "${jms.listener.destination}", selector = "${jms.listener.selector}",
131+
subscription = "${jms.listener.subscription}", concurrency = "${jms.listener.concurrency}")
117132
public String fullHandle(String msg) {
118133
return "reply";
119134
}

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,13 @@ public void fullConfiguration() {
5151
testFullConfiguration(context);
5252
}
5353

54+
@Override
55+
public void fullConfigurableConfiguration() {
56+
ApplicationContext context = new ClassPathXmlApplicationContext(
57+
"annotation-driven-full-configurable-config.xml", getClass());
58+
testFullConfiguration(context);
59+
}
60+
5461
@Override
5562
@Test
5663
public void customConfiguration() {

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

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
3030
import org.springframework.context.annotation.Bean;
3131
import org.springframework.context.annotation.Configuration;
32+
import org.springframework.context.annotation.PropertySource;
33+
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
3234
import org.springframework.messaging.handler.annotation.support.DefaultMessageHandlerMethodFactory;
3335
import org.springframework.messaging.handler.annotation.support.MessageHandlerMethodFactory;
3436
import org.springframework.jms.config.JmsListenerContainerTestFactory;
@@ -63,6 +65,13 @@ public void fullConfiguration() {
6365
testFullConfiguration(context);
6466
}
6567

68+
@Override
69+
public void fullConfigurableConfiguration() {
70+
ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(
71+
EnableJmsFullConfigurableConfig.class, FullConfigurableBean.class);
72+
testFullConfiguration(context);
73+
}
74+
6675
@Override
6776
@Test
6877
public void customConfiguration() {
@@ -131,6 +140,22 @@ public JmsListenerContainerTestFactory simpleFactory() {
131140
}
132141
}
133142

143+
@EnableJms
144+
@Configuration
145+
@PropertySource("classpath:/org/springframework/jms/annotation/jms-listener.properties")
146+
static class EnableJmsFullConfigurableConfig {
147+
148+
@Bean
149+
public JmsListenerContainerTestFactory simpleFactory() {
150+
return new JmsListenerContainerTestFactory();
151+
}
152+
153+
@Bean
154+
public PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
155+
return new PropertySourcesPlaceholderConfigurer();
156+
}
157+
}
158+
134159
@Configuration
135160
@EnableJms
136161
static class EnableJmsCustomConfig implements JmsListenerConfigurer {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<beans xmlns="http://www.springframework.org/schema/beans"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xmlns:jms="http://www.springframework.org/schema/jms"
5+
xmlns:context="http://www.springframework.org/schema/context"
6+
xsi:schemaLocation="http://www.springframework.org/schema/beans
7+
http://www.springframework.org/schema/beans/spring-beans.xsd
8+
http://www.springframework.org/schema/jms
9+
http://www.springframework.org/schema/jms/spring-jms-4.1.xsd
10+
http://www.springframework.org/schema/context
11+
http://www.springframework.org/schema/context/spring-context.xsd">
12+
13+
<jms:annotation-driven/>
14+
15+
<bean class="org.springframework.jms.annotation.AbstractJmsAnnotationDrivenTests$FullConfigurableBean"/>
16+
17+
<bean id="simpleFactory" class="org.springframework.jms.config.JmsListenerContainerTestFactory"/>
18+
19+
<context:property-placeholder location="classpath:org/springframework/jms/annotation/jms-listener.properties"/>
20+
21+
22+
</beans>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
jms.listener.id=listener1
2+
jms.listener.containerFactory=simpleFactory
3+
jms.listener.destination=queueIn
4+
jms.listener.selector=mySelector
5+
jms.listener.subscription=mySubscription
6+
jms.listener.concurrency=1-10

0 commit comments

Comments
 (0)