Revised method selection for JMS listeners (and their parameters)
Issue: SPR-13576
This commit is contained in:
@@ -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.
|
||||
@@ -26,6 +26,7 @@ import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
|
||||
import org.springframework.aop.support.AopUtils;
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
@@ -58,8 +59,9 @@ public class JmsListenerAnnotationBeanPostProcessorTests {
|
||||
@Rule
|
||||
public final ExpectedException thrown = ExpectedException.none();
|
||||
|
||||
|
||||
@Test
|
||||
public void simpleMessageListener() {
|
||||
public void simpleMessageListener() throws Exception {
|
||||
ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(
|
||||
Config.class, SimpleMessageListenerTestBean.class);
|
||||
|
||||
@@ -70,8 +72,9 @@ public class JmsListenerAnnotationBeanPostProcessorTests {
|
||||
JmsListenerEndpoint endpoint = container.getEndpoint();
|
||||
assertEquals("Wrong endpoint type", MethodJmsListenerEndpoint.class, endpoint.getClass());
|
||||
MethodJmsListenerEndpoint methodEndpoint = (MethodJmsListenerEndpoint) endpoint;
|
||||
assertNotNull(methodEndpoint.getBean());
|
||||
assertNotNull(methodEndpoint.getMethod());
|
||||
assertEquals(SimpleMessageListenerTestBean.class, methodEndpoint.getBean().getClass());
|
||||
assertEquals(SimpleMessageListenerTestBean.class.getMethod("handleIt", String.class), methodEndpoint.getMethod());
|
||||
assertEquals(SimpleMessageListenerTestBean.class.getMethod("handleIt", String.class), methodEndpoint.getMostSpecificMethod());
|
||||
|
||||
SimpleMessageListenerContainer listenerContainer = new SimpleMessageListenerContainer();
|
||||
methodEndpoint.setupListenerContainer(listenerContainer);
|
||||
@@ -83,14 +86,20 @@ public class JmsListenerAnnotationBeanPostProcessorTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void metaAnnotationIsDiscovered() {
|
||||
public void metaAnnotationIsDiscovered() throws Exception {
|
||||
ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(
|
||||
Config.class, MetaAnnotationTestBean.class);
|
||||
|
||||
try {
|
||||
JmsListenerContainerTestFactory factory = context.getBean(JmsListenerContainerTestFactory.class);
|
||||
assertEquals("one container should have been registered", 1, factory.getListenerContainers().size());
|
||||
|
||||
JmsListenerEndpoint endpoint = factory.getListenerContainers().get(0).getEndpoint();
|
||||
assertEquals("Wrong endpoint type", MethodJmsListenerEndpoint.class, endpoint.getClass());
|
||||
MethodJmsListenerEndpoint methodEndpoint = (MethodJmsListenerEndpoint) endpoint;
|
||||
assertEquals(MetaAnnotationTestBean.class, methodEndpoint.getBean().getClass());
|
||||
assertEquals(MetaAnnotationTestBean.class.getMethod("handleIt", String.class), methodEndpoint.getMethod());
|
||||
assertEquals(MetaAnnotationTestBean.class.getMethod("handleIt", String.class), methodEndpoint.getMostSpecificMethod());
|
||||
assertEquals("metaTestQueue", ((AbstractJmsListenerEndpoint) endpoint).getDestination());
|
||||
}
|
||||
finally {
|
||||
@@ -99,13 +108,21 @@ public class JmsListenerAnnotationBeanPostProcessorTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sendToAnnotationFoundOnProxy() {
|
||||
public void sendToAnnotationFoundOnProxy() throws Exception {
|
||||
ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(
|
||||
Config.class, ProxyConfig.class, ProxyTestBean.class);
|
||||
try {
|
||||
JmsListenerContainerTestFactory factory = context.getBean(JmsListenerContainerTestFactory.class);
|
||||
assertEquals("one container should have been registered", 1, factory.getListenerContainers().size());
|
||||
|
||||
JmsListenerEndpoint endpoint = factory.getListenerContainers().get(0).getEndpoint();
|
||||
assertEquals("Wrong endpoint type", MethodJmsListenerEndpoint.class, endpoint.getClass());
|
||||
MethodJmsListenerEndpoint methodEndpoint = (MethodJmsListenerEndpoint) endpoint;
|
||||
assertTrue(AopUtils.isJdkDynamicProxy(methodEndpoint.getBean()));
|
||||
assertTrue(methodEndpoint.getBean() instanceof SimpleService);
|
||||
assertEquals(SimpleService.class.getMethod("handleIt", String.class), methodEndpoint.getMethod());
|
||||
assertEquals(ProxyTestBean.class.getMethod("handleIt", String.class), methodEndpoint.getMostSpecificMethod());
|
||||
|
||||
Method m = ReflectionUtils.findMethod(endpoint.getClass(), "getDefaultResponseDestination");
|
||||
ReflectionUtils.makeAccessible(m);
|
||||
Object destination = ReflectionUtils.invokeMethod(m, endpoint);
|
||||
@@ -132,7 +149,6 @@ public class JmsListenerAnnotationBeanPostProcessorTests {
|
||||
@JmsListener(destination = "testQueue")
|
||||
public void handleIt(String body) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -174,6 +190,7 @@ public class JmsListenerAnnotationBeanPostProcessorTests {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Configuration
|
||||
@EnableTransactionManagement
|
||||
static class ProxyConfig {
|
||||
@@ -182,15 +199,15 @@ public class JmsListenerAnnotationBeanPostProcessorTests {
|
||||
public PlatformTransactionManager transactionManager() {
|
||||
return mock(PlatformTransactionManager.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
interface SimpleService {
|
||||
|
||||
void handleIt(String body);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Component
|
||||
static class ProxyTestBean implements SimpleService {
|
||||
|
||||
@@ -199,10 +216,10 @@ public class JmsListenerAnnotationBeanPostProcessorTests {
|
||||
@JmsListener(destination = "testQueue")
|
||||
@SendTo("foobar")
|
||||
public void handleIt(String body) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Component
|
||||
static class InvalidProxyTestBean implements SimpleService {
|
||||
|
||||
|
||||
@@ -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.
|
||||
@@ -29,12 +29,14 @@ import javax.jms.TextMessage;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.aop.framework.ProxyFactory;
|
||||
import org.springframework.beans.factory.support.StaticListableBeanFactory;
|
||||
import org.springframework.jms.StubTextMessage;
|
||||
import org.springframework.jms.listener.DefaultMessageListenerContainer;
|
||||
import org.springframework.jms.listener.SessionAwareMessageListener;
|
||||
import org.springframework.jms.support.converter.MessageConversionException;
|
||||
import org.springframework.jms.support.converter.MessageConverter;
|
||||
import org.springframework.messaging.handler.annotation.Header;
|
||||
import org.springframework.messaging.handler.annotation.Payload;
|
||||
import org.springframework.messaging.handler.annotation.support.DefaultMessageHandlerMethodFactory;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
@@ -53,27 +55,65 @@ public class JmsListenerContainerFactoryIntegrationTests {
|
||||
|
||||
private final JmsEndpointSampleBean sample = new JmsEndpointSampleBean();
|
||||
|
||||
private JmsEndpointSampleInterface listener = sample;
|
||||
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
initializeFactory(factory);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void messageConverterUsedIfSet() throws JMSException {
|
||||
containerFactory.setMessageConverter(new UpperCaseMessageConverter());
|
||||
|
||||
MethodJmsListenerEndpoint endpoint = createDefaultMethodJmsEndpoint("expectFooBarUpperCase", String.class);
|
||||
MethodJmsListenerEndpoint endpoint = createDefaultMethodJmsEndpoint(
|
||||
listener.getClass(), "handleIt", String.class, String.class);
|
||||
Message message = new StubTextMessage("foo-bar");
|
||||
message.setStringProperty("my-header", "my-value");
|
||||
|
||||
invokeListener(endpoint, message);
|
||||
assertListenerMethodInvocation("expectFooBarUpperCase");
|
||||
assertListenerMethodInvocation("handleIt");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parameterAnnotationWithJdkProxy() throws JMSException {
|
||||
ProxyFactory pf = new ProxyFactory(sample);
|
||||
listener = (JmsEndpointSampleInterface) pf.getProxy();
|
||||
|
||||
containerFactory.setMessageConverter(new UpperCaseMessageConverter());
|
||||
|
||||
MethodJmsListenerEndpoint endpoint = createDefaultMethodJmsEndpoint(
|
||||
JmsEndpointSampleInterface.class, "handleIt", String.class, String.class);
|
||||
Message message = new StubTextMessage("foo-bar");
|
||||
message.setStringProperty("my-header", "my-value");
|
||||
|
||||
invokeListener(endpoint, message);
|
||||
assertListenerMethodInvocation("handleIt");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parameterAnnotationWithCglibProxy() throws JMSException {
|
||||
ProxyFactory pf = new ProxyFactory(sample);
|
||||
pf.setProxyTargetClass(true);
|
||||
listener = (JmsEndpointSampleBean) pf.getProxy();
|
||||
|
||||
containerFactory.setMessageConverter(new UpperCaseMessageConverter());
|
||||
|
||||
MethodJmsListenerEndpoint endpoint = createDefaultMethodJmsEndpoint(
|
||||
JmsEndpointSampleBean.class, "handleIt", String.class, String.class);
|
||||
Message message = new StubTextMessage("foo-bar");
|
||||
message.setStringProperty("my-header", "my-value");
|
||||
|
||||
invokeListener(endpoint, message);
|
||||
assertListenerMethodInvocation("handleIt");
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void invokeListener(JmsListenerEndpoint endpoint, Message message) throws JMSException {
|
||||
DefaultMessageListenerContainer messageListenerContainer =
|
||||
containerFactory.createListenerContainer(endpoint);
|
||||
DefaultMessageListenerContainer messageListenerContainer = containerFactory.createListenerContainer(endpoint);
|
||||
Object listener = messageListenerContainer.getMessageListener();
|
||||
if (listener instanceof SessionAwareMessageListener) {
|
||||
((SessionAwareMessageListener<Message>) listener).onMessage(message, mock(Session.class));
|
||||
@@ -87,40 +127,38 @@ public class JmsListenerContainerFactoryIntegrationTests {
|
||||
assertTrue("Method " + methodName + " should have been invoked", sample.invocations.get(methodName));
|
||||
}
|
||||
|
||||
|
||||
private MethodJmsListenerEndpoint createMethodJmsEndpoint(
|
||||
DefaultMessageHandlerMethodFactory factory, Method method) {
|
||||
private MethodJmsListenerEndpoint createMethodJmsEndpoint(DefaultMessageHandlerMethodFactory factory, Method method) {
|
||||
MethodJmsListenerEndpoint endpoint = new MethodJmsListenerEndpoint();
|
||||
endpoint.setBean(sample);
|
||||
endpoint.setBean(listener);
|
||||
endpoint.setMethod(method);
|
||||
endpoint.setMessageHandlerMethodFactory(factory);
|
||||
return endpoint;
|
||||
}
|
||||
|
||||
private MethodJmsListenerEndpoint createDefaultMethodJmsEndpoint(String methodName, Class<?>... parameterTypes) {
|
||||
return createMethodJmsEndpoint(this.factory, getListenerMethod(methodName, parameterTypes));
|
||||
private MethodJmsListenerEndpoint createDefaultMethodJmsEndpoint(Class<?> clazz, String methodName, Class<?>... paramTypes) {
|
||||
return createMethodJmsEndpoint(this.factory, ReflectionUtils.findMethod(clazz, methodName, paramTypes));
|
||||
}
|
||||
|
||||
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));
|
||||
return method;
|
||||
}
|
||||
|
||||
|
||||
private void initializeFactory(DefaultMessageHandlerMethodFactory factory) {
|
||||
factory.setBeanFactory(new StaticListableBeanFactory());
|
||||
factory.afterPropertiesSet();
|
||||
}
|
||||
|
||||
|
||||
static class JmsEndpointSampleBean {
|
||||
interface JmsEndpointSampleInterface {
|
||||
|
||||
void handleIt(@Payload String msg, @Header("my-header") String myHeader);
|
||||
}
|
||||
|
||||
|
||||
static class JmsEndpointSampleBean implements JmsEndpointSampleInterface {
|
||||
|
||||
private final Map<String, Boolean> invocations = new HashMap<String, Boolean>();
|
||||
|
||||
public void expectFooBarUpperCase(@Payload String msg) {
|
||||
invocations.put("expectFooBarUpperCase", true);
|
||||
public void handleIt(@Payload String msg, @Header("my-header") String myHeader) {
|
||||
invocations.put("handleIt", true);
|
||||
assertEquals("Unexpected payload message", "FOO-BAR", msg);
|
||||
assertEquals("Unexpected header value", "my-value", myHeader);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user