Post-processors consistently ignore ScopedObject/AopInfrastructureBean
Issue: SPR-17166
This commit is contained in:
@@ -327,7 +327,7 @@ public class ScheduledAnnotationBeanPostProcessor
|
|||||||
if (annotatedMethods.isEmpty()) {
|
if (annotatedMethods.isEmpty()) {
|
||||||
this.nonAnnotatedClasses.add(targetClass);
|
this.nonAnnotatedClasses.add(targetClass);
|
||||||
if (logger.isTraceEnabled()) {
|
if (logger.isTraceEnabled()) {
|
||||||
logger.trace("No @Scheduled annotations found on bean class: " + bean.getClass());
|
logger.trace("No @Scheduled annotations found on bean class: " + targetClass);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
|
import org.springframework.aop.framework.AopInfrastructureBean;
|
||||||
import org.springframework.aop.framework.AopProxyUtils;
|
import org.springframework.aop.framework.AopProxyUtils;
|
||||||
import org.springframework.aop.support.AopUtils;
|
import org.springframework.aop.support.AopUtils;
|
||||||
import org.springframework.beans.BeansException;
|
import org.springframework.beans.BeansException;
|
||||||
@@ -96,10 +97,10 @@ public class JmsListenerAnnotationBeanPostProcessor
|
|||||||
|
|
||||||
protected final Log logger = LogFactory.getLog(getClass());
|
protected final Log logger = LogFactory.getLog(getClass());
|
||||||
|
|
||||||
private JmsListenerEndpointRegistry endpointRegistry;
|
|
||||||
|
|
||||||
private String containerFactoryBeanName = DEFAULT_JMS_LISTENER_CONTAINER_FACTORY_BEAN_NAME;
|
private String containerFactoryBeanName = DEFAULT_JMS_LISTENER_CONTAINER_FACTORY_BEAN_NAME;
|
||||||
|
|
||||||
|
private JmsListenerEndpointRegistry endpointRegistry;
|
||||||
|
|
||||||
private final MessageHandlerMethodFactoryAdapter messageHandlerMethodFactory =
|
private final MessageHandlerMethodFactoryAdapter messageHandlerMethodFactory =
|
||||||
new MessageHandlerMethodFactoryAdapter();
|
new MessageHandlerMethodFactoryAdapter();
|
||||||
|
|
||||||
@@ -120,14 +121,6 @@ public class JmsListenerAnnotationBeanPostProcessor
|
|||||||
return LOWEST_PRECEDENCE;
|
return LOWEST_PRECEDENCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the {@link JmsListenerEndpointRegistry} that will hold the created
|
|
||||||
* endpoint and manage the lifecycle of the related listener container.
|
|
||||||
*/
|
|
||||||
public void setEndpointRegistry(JmsListenerEndpointRegistry endpointRegistry) {
|
|
||||||
this.endpointRegistry = endpointRegistry;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the name of the {@link JmsListenerContainerFactory} to use by default.
|
* Set the name of the {@link JmsListenerContainerFactory} to use by default.
|
||||||
* <p>If none is specified, "jmsListenerContainerFactory" is assumed to be defined.
|
* <p>If none is specified, "jmsListenerContainerFactory" is assumed to be defined.
|
||||||
@@ -136,6 +129,14 @@ public class JmsListenerAnnotationBeanPostProcessor
|
|||||||
this.containerFactoryBeanName = containerFactoryBeanName;
|
this.containerFactoryBeanName = containerFactoryBeanName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the {@link JmsListenerEndpointRegistry} that will hold the created
|
||||||
|
* endpoint and manage the lifecycle of the related listener container.
|
||||||
|
*/
|
||||||
|
public void setEndpointRegistry(JmsListenerEndpointRegistry endpointRegistry) {
|
||||||
|
this.endpointRegistry = endpointRegistry;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the {@link MessageHandlerMethodFactory} to use to configure the message
|
* Set the {@link MessageHandlerMethodFactory} to use to configure the message
|
||||||
* listener responsible to serve an endpoint detected by this processor.
|
* listener responsible to serve an endpoint detected by this processor.
|
||||||
@@ -179,6 +180,10 @@ public class JmsListenerAnnotationBeanPostProcessor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.containerFactoryBeanName != null) {
|
||||||
|
this.registrar.setContainerFactoryBeanName(this.containerFactoryBeanName);
|
||||||
|
}
|
||||||
|
|
||||||
if (this.registrar.getEndpointRegistry() == null) {
|
if (this.registrar.getEndpointRegistry() == null) {
|
||||||
// Determine JmsListenerEndpointRegistry bean from the BeanFactory
|
// Determine JmsListenerEndpointRegistry bean from the BeanFactory
|
||||||
if (this.endpointRegistry == null) {
|
if (this.endpointRegistry == null) {
|
||||||
@@ -189,9 +194,6 @@ public class JmsListenerAnnotationBeanPostProcessor
|
|||||||
this.registrar.setEndpointRegistry(this.endpointRegistry);
|
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
|
// Set the custom handler method factory once resolved by the configurer
|
||||||
MessageHandlerMethodFactory handlerMethodFactory = this.registrar.getMessageHandlerMethodFactory();
|
MessageHandlerMethodFactory handlerMethodFactory = this.registrar.getMessageHandlerMethodFactory();
|
||||||
@@ -215,8 +217,13 @@ public class JmsListenerAnnotationBeanPostProcessor
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object postProcessAfterInitialization(final Object bean, String beanName) throws BeansException {
|
public Object postProcessAfterInitialization(final Object bean, String beanName) throws BeansException {
|
||||||
if (!this.nonAnnotatedClasses.contains(bean.getClass())) {
|
if (bean instanceof AopInfrastructureBean) {
|
||||||
Class<?> targetClass = AopProxyUtils.ultimateTargetClass(bean);
|
// Ignore AOP infrastructure such as scoped proxies.
|
||||||
|
return bean;
|
||||||
|
}
|
||||||
|
|
||||||
|
Class<?> targetClass = AopProxyUtils.ultimateTargetClass(bean);
|
||||||
|
if (!this.nonAnnotatedClasses.contains(targetClass)) {
|
||||||
Map<Method, Set<JmsListener>> annotatedMethods = MethodIntrospector.selectMethods(targetClass,
|
Map<Method, Set<JmsListener>> annotatedMethods = MethodIntrospector.selectMethods(targetClass,
|
||||||
new MethodIntrospector.MetadataLookup<Set<JmsListener>>() {
|
new MethodIntrospector.MetadataLookup<Set<JmsListener>>() {
|
||||||
@Override
|
@Override
|
||||||
@@ -227,9 +234,9 @@ public class JmsListenerAnnotationBeanPostProcessor
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (annotatedMethods.isEmpty()) {
|
if (annotatedMethods.isEmpty()) {
|
||||||
this.nonAnnotatedClasses.add(bean.getClass());
|
this.nonAnnotatedClasses.add(targetClass);
|
||||||
if (logger.isTraceEnabled()) {
|
if (logger.isTraceEnabled()) {
|
||||||
logger.trace("No @JmsListener annotations found on bean type: " + bean.getClass());
|
logger.trace("No @JmsListener annotations found on bean type: " + targetClass);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2016 the original author or authors.
|
* Copyright 2002-2018 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -39,6 +39,7 @@ import org.springframework.jms.config.JmsListenerEndpointRegistry;
|
|||||||
import org.springframework.jms.config.MessageListenerTestContainer;
|
import org.springframework.jms.config.MessageListenerTestContainer;
|
||||||
import org.springframework.jms.config.MethodJmsListenerEndpoint;
|
import org.springframework.jms.config.MethodJmsListenerEndpoint;
|
||||||
import org.springframework.jms.listener.SimpleMessageListenerContainer;
|
import org.springframework.jms.listener.SimpleMessageListenerContainer;
|
||||||
|
import org.springframework.messaging.handler.annotation.Header;
|
||||||
import org.springframework.messaging.handler.annotation.SendTo;
|
import org.springframework.messaging.handler.annotation.SendTo;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.transaction.PlatformTransactionManager;
|
import org.springframework.transaction.PlatformTransactionManager;
|
||||||
@@ -73,8 +74,10 @@ public class JmsListenerAnnotationBeanPostProcessorTests {
|
|||||||
assertEquals("Wrong endpoint type", MethodJmsListenerEndpoint.class, endpoint.getClass());
|
assertEquals("Wrong endpoint type", MethodJmsListenerEndpoint.class, endpoint.getClass());
|
||||||
MethodJmsListenerEndpoint methodEndpoint = (MethodJmsListenerEndpoint) endpoint;
|
MethodJmsListenerEndpoint methodEndpoint = (MethodJmsListenerEndpoint) endpoint;
|
||||||
assertEquals(SimpleMessageListenerTestBean.class, methodEndpoint.getBean().getClass());
|
assertEquals(SimpleMessageListenerTestBean.class, methodEndpoint.getBean().getClass());
|
||||||
assertEquals(SimpleMessageListenerTestBean.class.getMethod("handleIt", String.class), methodEndpoint.getMethod());
|
assertEquals(SimpleMessageListenerTestBean.class.getMethod("handleIt", String.class),
|
||||||
assertEquals(SimpleMessageListenerTestBean.class.getMethod("handleIt", String.class), methodEndpoint.getMostSpecificMethod());
|
methodEndpoint.getMethod());
|
||||||
|
assertEquals(SimpleMessageListenerTestBean.class.getMethod("handleIt", String.class),
|
||||||
|
methodEndpoint.getMostSpecificMethod());
|
||||||
|
|
||||||
SimpleMessageListenerContainer listenerContainer = new SimpleMessageListenerContainer();
|
SimpleMessageListenerContainer listenerContainer = new SimpleMessageListenerContainer();
|
||||||
methodEndpoint.setupListenerContainer(listenerContainer);
|
methodEndpoint.setupListenerContainer(listenerContainer);
|
||||||
@@ -98,8 +101,10 @@ public class JmsListenerAnnotationBeanPostProcessorTests {
|
|||||||
assertEquals("Wrong endpoint type", MethodJmsListenerEndpoint.class, endpoint.getClass());
|
assertEquals("Wrong endpoint type", MethodJmsListenerEndpoint.class, endpoint.getClass());
|
||||||
MethodJmsListenerEndpoint methodEndpoint = (MethodJmsListenerEndpoint) endpoint;
|
MethodJmsListenerEndpoint methodEndpoint = (MethodJmsListenerEndpoint) endpoint;
|
||||||
assertEquals(MetaAnnotationTestBean.class, methodEndpoint.getBean().getClass());
|
assertEquals(MetaAnnotationTestBean.class, methodEndpoint.getBean().getClass());
|
||||||
assertEquals(MetaAnnotationTestBean.class.getMethod("handleIt", String.class), methodEndpoint.getMethod());
|
assertEquals(MetaAnnotationTestBean.class.getMethod("handleIt", String.class),
|
||||||
assertEquals(MetaAnnotationTestBean.class.getMethod("handleIt", String.class), methodEndpoint.getMostSpecificMethod());
|
methodEndpoint.getMethod());
|
||||||
|
assertEquals(MetaAnnotationTestBean.class.getMethod("handleIt", String.class),
|
||||||
|
methodEndpoint.getMostSpecificMethod());
|
||||||
assertEquals("metaTestQueue", ((AbstractJmsListenerEndpoint) endpoint).getDestination());
|
assertEquals("metaTestQueue", ((AbstractJmsListenerEndpoint) endpoint).getDestination());
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
@@ -108,9 +113,9 @@ public class JmsListenerAnnotationBeanPostProcessorTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void sendToAnnotationFoundOnProxy() throws Exception {
|
public void sendToAnnotationFoundOnInterfaceProxy() throws Exception {
|
||||||
ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(
|
ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(
|
||||||
Config.class, ProxyConfig.class, ProxyTestBean.class);
|
Config.class, ProxyConfig.class, InterfaceProxyTestBean.class);
|
||||||
try {
|
try {
|
||||||
JmsListenerContainerTestFactory factory = context.getBean(JmsListenerContainerTestFactory.class);
|
JmsListenerContainerTestFactory factory = context.getBean(JmsListenerContainerTestFactory.class);
|
||||||
assertEquals("one container should have been registered", 1, factory.getListenerContainers().size());
|
assertEquals("one container should have been registered", 1, factory.getListenerContainers().size());
|
||||||
@@ -120,12 +125,42 @@ public class JmsListenerAnnotationBeanPostProcessorTests {
|
|||||||
MethodJmsListenerEndpoint methodEndpoint = (MethodJmsListenerEndpoint) endpoint;
|
MethodJmsListenerEndpoint methodEndpoint = (MethodJmsListenerEndpoint) endpoint;
|
||||||
assertTrue(AopUtils.isJdkDynamicProxy(methodEndpoint.getBean()));
|
assertTrue(AopUtils.isJdkDynamicProxy(methodEndpoint.getBean()));
|
||||||
assertTrue(methodEndpoint.getBean() instanceof SimpleService);
|
assertTrue(methodEndpoint.getBean() instanceof SimpleService);
|
||||||
assertEquals(SimpleService.class.getMethod("handleIt", String.class), methodEndpoint.getMethod());
|
assertEquals(SimpleService.class.getMethod("handleIt", String.class, String.class),
|
||||||
assertEquals(ProxyTestBean.class.getMethod("handleIt", String.class), methodEndpoint.getMostSpecificMethod());
|
methodEndpoint.getMethod());
|
||||||
|
assertEquals(InterfaceProxyTestBean.class.getMethod("handleIt", String.class, String.class),
|
||||||
|
methodEndpoint.getMostSpecificMethod());
|
||||||
|
|
||||||
Method m = ReflectionUtils.findMethod(endpoint.getClass(), "getDefaultResponseDestination");
|
Method method = ReflectionUtils.findMethod(endpoint.getClass(), "getDefaultResponseDestination");
|
||||||
ReflectionUtils.makeAccessible(m);
|
ReflectionUtils.makeAccessible(method);
|
||||||
Object destination = ReflectionUtils.invokeMethod(m, endpoint);
|
Object destination = ReflectionUtils.invokeMethod(method, endpoint);
|
||||||
|
assertEquals("SendTo annotation not found on proxy", "foobar", destination);
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
context.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void sendToAnnotationFoundOnCglibProxy() throws Exception {
|
||||||
|
ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(
|
||||||
|
Config.class, ProxyConfig.class, ClassProxyTestBean.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.isCglibProxy(methodEndpoint.getBean()));
|
||||||
|
assertTrue(methodEndpoint.getBean() instanceof ClassProxyTestBean);
|
||||||
|
assertEquals(ClassProxyTestBean.class.getMethod("handleIt", String.class, String.class),
|
||||||
|
methodEndpoint.getMethod());
|
||||||
|
assertEquals(ClassProxyTestBean.class.getMethod("handleIt", String.class, String.class),
|
||||||
|
methodEndpoint.getMostSpecificMethod());
|
||||||
|
|
||||||
|
Method method = ReflectionUtils.findMethod(endpoint.getClass(), "getDefaultResponseDestination");
|
||||||
|
ReflectionUtils.makeAccessible(method);
|
||||||
|
Object destination = ReflectionUtils.invokeMethod(method, endpoint);
|
||||||
assertEquals("SendTo annotation not found on proxy", "foobar", destination);
|
assertEquals("SendTo annotation not found on proxy", "foobar", destination);
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
@@ -174,8 +209,8 @@ public class JmsListenerAnnotationBeanPostProcessorTests {
|
|||||||
@Bean
|
@Bean
|
||||||
public JmsListenerAnnotationBeanPostProcessor postProcessor() {
|
public JmsListenerAnnotationBeanPostProcessor postProcessor() {
|
||||||
JmsListenerAnnotationBeanPostProcessor postProcessor = new JmsListenerAnnotationBeanPostProcessor();
|
JmsListenerAnnotationBeanPostProcessor postProcessor = new JmsListenerAnnotationBeanPostProcessor();
|
||||||
postProcessor.setEndpointRegistry(jmsListenerEndpointRegistry());
|
|
||||||
postProcessor.setContainerFactoryBeanName("testFactory");
|
postProcessor.setContainerFactoryBeanName("testFactory");
|
||||||
|
postProcessor.setEndpointRegistry(jmsListenerEndpointRegistry());
|
||||||
return postProcessor;
|
return postProcessor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -204,18 +239,29 @@ public class JmsListenerAnnotationBeanPostProcessorTests {
|
|||||||
|
|
||||||
interface SimpleService {
|
interface SimpleService {
|
||||||
|
|
||||||
void handleIt(String body);
|
void handleIt(String value, String body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
static class ProxyTestBean implements SimpleService {
|
static class InterfaceProxyTestBean implements SimpleService {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
@JmsListener(destination = "testQueue")
|
@JmsListener(destination = "testQueue")
|
||||||
@SendTo("foobar")
|
@SendTo("foobar")
|
||||||
public void handleIt(String body) {
|
public void handleIt(@Header String value, String body) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Component
|
||||||
|
static class ClassProxyTestBean {
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
@JmsListener(destination = "testQueue")
|
||||||
|
@SendTo("foobar")
|
||||||
|
public void handleIt(@Header String value, String body) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -224,7 +270,7 @@ public class JmsListenerAnnotationBeanPostProcessorTests {
|
|||||||
static class InvalidProxyTestBean implements SimpleService {
|
static class InvalidProxyTestBean implements SimpleService {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleIt(String body) {
|
public void handleIt(String value, String body) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
|
|||||||
Reference in New Issue
Block a user