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 54b8e98f80..ce245f609d 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 @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2015 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. @@ -247,6 +247,7 @@ public class JmsListenerAnnotationBeanPostProcessor endpoint.setBean(bean); endpoint.setMethod(method); endpoint.setMessageHandlerMethodFactory(this.messageHandlerMethodFactory); + endpoint.setBeanFactory(this.beanFactory); endpoint.setId(getEndpointId(jmsListener)); endpoint.setDestination(resolve(jmsListener.destination())); if (StringUtils.hasText(jmsListener.selector())) { diff --git a/spring-jms/src/main/java/org/springframework/jms/config/MethodJmsListenerEndpoint.java b/spring-jms/src/main/java/org/springframework/jms/config/MethodJmsListenerEndpoint.java index 848ff3d593..013146b95a 100644 --- a/spring-jms/src/main/java/org/springframework/jms/config/MethodJmsListenerEndpoint.java +++ b/spring-jms/src/main/java/org/springframework/jms/config/MethodJmsListenerEndpoint.java @@ -21,6 +21,8 @@ import java.util.Arrays; import org.springframework.aop.framework.AopProxyUtils; import org.springframework.aop.support.AopUtils; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.jms.listener.MessageListenerContainer; import org.springframework.jms.listener.adapter.MessagingMessageListenerAdapter; @@ -46,6 +48,8 @@ public class MethodJmsListenerEndpoint extends AbstractJmsListenerEndpoint { private MessageHandlerMethodFactory messageHandlerMethodFactory; + private BeanFactory beanFactory; + /** * Set the object instance that should manage this endpoint. @@ -78,6 +82,12 @@ public class MethodJmsListenerEndpoint extends AbstractJmsListenerEndpoint { this.messageHandlerMethodFactory = messageHandlerMethodFactory; } + /** + * Set the {@link BeanFactory} to use to resolve expressions (can be null). + */ + public void setBeanFactory(BeanFactory beanFactory) { + this.beanFactory = beanFactory; + } @Override protected MessagingMessageListenerAdapter createMessageListener(MessageListenerContainer container) { @@ -110,7 +120,10 @@ public class MethodJmsListenerEndpoint extends AbstractJmsListenerEndpoint { return new MessagingMessageListenerAdapter(); } - private String getDefaultResponseDestination() { + /** + * Return the default response destination, if any. + */ + protected String getDefaultResponseDestination() { Method specificMethod = getMostSpecificMethod(); SendTo ann = AnnotationUtils.getAnnotation(specificMethod, SendTo.class); if (ann != null) { @@ -119,11 +132,23 @@ public class MethodJmsListenerEndpoint extends AbstractJmsListenerEndpoint { throw new IllegalStateException("Invalid @" + SendTo.class.getSimpleName() + " annotation on '" + specificMethod + "' one destination must be set (got " + Arrays.toString(destinations) + ")"); } - return (String) destinations[0]; + return resolve((String) destinations[0]); } return null; } + /** + * Resolve the specified value if possible. + * @see ConfigurableBeanFactory#resolveEmbeddedValue + */ + private String resolve(String value) { + if (this.beanFactory instanceof ConfigurableBeanFactory) { + return ((ConfigurableBeanFactory) this.beanFactory).resolveEmbeddedValue(value); + } + return value; + } + + private Method getMostSpecificMethod() { if (AopUtils.isAopProxy(this.bean)) { Class target = AopProxyUtils.ultimateTargetClass(this.bean); 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 314f039e02..612f8693bd 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 @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2015 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. @@ -16,6 +16,7 @@ package org.springframework.jms.annotation; +import java.lang.reflect.Method; import javax.jms.JMSException; import javax.jms.Session; @@ -32,7 +33,9 @@ import org.springframework.jms.config.MethodJmsListenerEndpoint; import org.springframework.jms.config.SimpleJmsListenerEndpoint; import org.springframework.jms.listener.SimpleMessageListenerContainer; import org.springframework.jms.listener.adapter.MessagingMessageListenerAdapter; +import org.springframework.messaging.handler.annotation.SendTo; import org.springframework.stereotype.Component; +import org.springframework.util.ReflectionUtils; import org.springframework.validation.Errors; import org.springframework.validation.Validator; import org.springframework.validation.annotation.Validated; @@ -111,6 +114,11 @@ public abstract class AbstractJmsAnnotationDrivenTests { assertEquals("mySelector", endpoint.getSelector()); assertEquals("mySubscription", endpoint.getSubscription()); assertEquals("1-10", endpoint.getConcurrency()); + + Method m = ReflectionUtils.findMethod(endpoint.getClass(), "getDefaultResponseDestination"); + ReflectionUtils.makeAccessible(m); + Object destination = ReflectionUtils.invokeMethod(m, endpoint); + assertEquals("queueOut", destination); } @Component @@ -118,6 +126,7 @@ public abstract class AbstractJmsAnnotationDrivenTests { @JmsListener(id = "listener1", containerFactory = "simpleFactory", destination = "queueIn", selector = "mySelector", subscription = "mySubscription", concurrency = "1-10") + @SendTo("queueOut") public String fullHandle(String msg) { return "reply"; } @@ -129,6 +138,7 @@ public abstract class AbstractJmsAnnotationDrivenTests { @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}") + @SendTo("${jms.listener.sendTo}") public String fullHandle(String msg) { return "reply"; } 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 index 18459dcffe..b579fbcb4b 100644 --- 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 @@ -3,4 +3,5 @@ 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 +jms.listener.concurrency=1-10 +jms.listener.sendTo=queueOut \ No newline at end of file