Post-processors consistently ignore ScopedObject/AopInfrastructureBean
JmsListenerAnnotationBeanPostProcessor also ignores JmsListenerContainerFactory and JmsListenerEndpointRegistry, avoiding unnecessary annotation introspection on framework classes. Issue: SPR-17166 Issue: SPR-16933
This commit is contained in:
parent
8d08935c49
commit
c4a7567a5e
|
|
@ -350,7 +350,7 @@ public class ScheduledAnnotationBeanPostProcessor
|
|||
if (annotatedMethods.isEmpty()) {
|
||||
this.nonAnnotatedClasses.add(targetClass);
|
||||
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 {
|
||||
|
|
@ -507,9 +507,7 @@ public class ScheduledAnnotationBeanPostProcessor
|
|||
* @see ScheduledMethodRunnable#ScheduledMethodRunnable(Object, Method)
|
||||
*/
|
||||
protected Runnable createRunnable(Object target, Method method) {
|
||||
Assert.isTrue(method.getParameterCount() == 0,
|
||||
"Only no-arg methods may be annotated with @Scheduled");
|
||||
|
||||
Assert.isTrue(method.getParameterCount() == 0, "Only no-arg methods may be annotated with @Scheduled");
|
||||
Method invocableMethod = AopUtils.selectInvocableMethod(method, target.getClass());
|
||||
return new ScheduledMethodRunnable(target, invocableMethod);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.aop.framework.AopInfrastructureBean;
|
||||
import org.springframework.aop.framework.AopProxyUtils;
|
||||
import org.springframework.aop.support.AopUtils;
|
||||
import org.springframework.beans.BeansException;
|
||||
|
|
@ -98,10 +99,10 @@ public class JmsListenerAnnotationBeanPostProcessor
|
|||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
@Nullable
|
||||
private JmsListenerEndpointRegistry endpointRegistry;
|
||||
private String containerFactoryBeanName = DEFAULT_JMS_LISTENER_CONTAINER_FACTORY_BEAN_NAME;
|
||||
|
||||
@Nullable
|
||||
private String containerFactoryBeanName = DEFAULT_JMS_LISTENER_CONTAINER_FACTORY_BEAN_NAME;
|
||||
private JmsListenerEndpointRegistry endpointRegistry;
|
||||
|
||||
private final MessageHandlerMethodFactoryAdapter messageHandlerMethodFactory =
|
||||
new MessageHandlerMethodFactoryAdapter();
|
||||
|
|
@ -124,14 +125,6 @@ public class JmsListenerAnnotationBeanPostProcessor
|
|||
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.
|
||||
* <p>If none is specified, "jmsListenerContainerFactory" is assumed to be defined.
|
||||
|
|
@ -140,6 +133,14 @@ public class JmsListenerAnnotationBeanPostProcessor
|
|||
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
|
||||
* listener responsible to serve an endpoint detected by this processor.
|
||||
|
|
@ -183,6 +184,10 @@ public class JmsListenerAnnotationBeanPostProcessor
|
|||
}
|
||||
}
|
||||
|
||||
if (this.containerFactoryBeanName != null) {
|
||||
this.registrar.setContainerFactoryBeanName(this.containerFactoryBeanName);
|
||||
}
|
||||
|
||||
if (this.registrar.getEndpointRegistry() == null) {
|
||||
// Determine JmsListenerEndpointRegistry bean from the BeanFactory
|
||||
if (this.endpointRegistry == null) {
|
||||
|
|
@ -193,9 +198,6 @@ public class JmsListenerAnnotationBeanPostProcessor
|
|||
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
|
||||
MessageHandlerMethodFactory handlerMethodFactory = this.registrar.getMessageHandlerMethodFactory();
|
||||
|
|
@ -218,9 +220,15 @@ public class JmsListenerAnnotationBeanPostProcessor
|
|||
}
|
||||
|
||||
@Override
|
||||
public Object postProcessAfterInitialization(final Object bean, String beanName) throws BeansException {
|
||||
if (!this.nonAnnotatedClasses.contains(bean.getClass())) {
|
||||
Class<?> targetClass = AopProxyUtils.ultimateTargetClass(bean);
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
|
||||
if (bean instanceof AopInfrastructureBean || bean instanceof JmsListenerContainerFactory ||
|
||||
bean instanceof JmsListenerEndpointRegistry) {
|
||||
// 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,
|
||||
(MethodIntrospector.MetadataLookup<Set<JmsListener>>) method -> {
|
||||
Set<JmsListener> listenerMethods = AnnotatedElementUtils.getMergedRepeatableAnnotations(
|
||||
|
|
@ -228,16 +236,15 @@ public class JmsListenerAnnotationBeanPostProcessor
|
|||
return (!listenerMethods.isEmpty() ? listenerMethods : null);
|
||||
});
|
||||
if (annotatedMethods.isEmpty()) {
|
||||
this.nonAnnotatedClasses.add(bean.getClass());
|
||||
this.nonAnnotatedClasses.add(targetClass);
|
||||
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 {
|
||||
// Non-empty set of methods
|
||||
annotatedMethods.forEach((method, listeners) ->
|
||||
listeners.forEach(listener ->
|
||||
processJmsListener(listener, method, bean)));
|
||||
listeners.forEach(listener -> processJmsListener(listener, method, bean)));
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(annotatedMethods.size() + " @JmsListener methods processed on bean '" + beanName +
|
||||
"': " + annotatedMethods);
|
||||
|
|
|
|||
|
|
@ -74,8 +74,10 @@ public class JmsListenerAnnotationBeanPostProcessorTests {
|
|||
assertEquals("Wrong endpoint type", MethodJmsListenerEndpoint.class, endpoint.getClass());
|
||||
MethodJmsListenerEndpoint methodEndpoint = (MethodJmsListenerEndpoint) endpoint;
|
||||
assertEquals(SimpleMessageListenerTestBean.class, methodEndpoint.getBean().getClass());
|
||||
assertEquals(SimpleMessageListenerTestBean.class.getMethod("handleIt", String.class), methodEndpoint.getMethod());
|
||||
assertEquals(SimpleMessageListenerTestBean.class.getMethod("handleIt", String.class), methodEndpoint.getMostSpecificMethod());
|
||||
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);
|
||||
|
|
@ -99,8 +101,10 @@ public class JmsListenerAnnotationBeanPostProcessorTests {
|
|||
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(MetaAnnotationTestBean.class.getMethod("handleIt", String.class),
|
||||
methodEndpoint.getMethod());
|
||||
assertEquals(MetaAnnotationTestBean.class.getMethod("handleIt", String.class),
|
||||
methodEndpoint.getMostSpecificMethod());
|
||||
assertEquals("metaTestQueue", ((AbstractJmsListenerEndpoint) endpoint).getDestination());
|
||||
}
|
||||
finally {
|
||||
|
|
@ -121,12 +125,14 @@ public class JmsListenerAnnotationBeanPostProcessorTests {
|
|||
MethodJmsListenerEndpoint methodEndpoint = (MethodJmsListenerEndpoint) endpoint;
|
||||
assertTrue(AopUtils.isJdkDynamicProxy(methodEndpoint.getBean()));
|
||||
assertTrue(methodEndpoint.getBean() instanceof SimpleService);
|
||||
assertEquals(SimpleService.class.getMethod("handleIt", String.class, String.class), methodEndpoint.getMethod());
|
||||
assertEquals(InterfaceProxyTestBean.class.getMethod("handleIt", String.class, String.class), methodEndpoint.getMostSpecificMethod());
|
||||
assertEquals(SimpleService.class.getMethod("handleIt", String.class, String.class),
|
||||
methodEndpoint.getMethod());
|
||||
assertEquals(InterfaceProxyTestBean.class.getMethod("handleIt", String.class, String.class),
|
||||
methodEndpoint.getMostSpecificMethod());
|
||||
|
||||
Method m = ReflectionUtils.findMethod(endpoint.getClass(), "getDefaultResponseDestination");
|
||||
ReflectionUtils.makeAccessible(m);
|
||||
Object destination = ReflectionUtils.invokeMethod(m, endpoint);
|
||||
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);
|
||||
}
|
||||
finally {
|
||||
|
|
@ -147,12 +153,14 @@ public class JmsListenerAnnotationBeanPostProcessorTests {
|
|||
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());
|
||||
assertEquals(ClassProxyTestBean.class.getMethod("handleIt", String.class, String.class),
|
||||
methodEndpoint.getMethod());
|
||||
assertEquals(ClassProxyTestBean.class.getMethod("handleIt", String.class, String.class),
|
||||
methodEndpoint.getMostSpecificMethod());
|
||||
|
||||
Method m = ReflectionUtils.findMethod(endpoint.getClass(), "getDefaultResponseDestination");
|
||||
ReflectionUtils.makeAccessible(m);
|
||||
Object destination = ReflectionUtils.invokeMethod(m, endpoint);
|
||||
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);
|
||||
}
|
||||
finally {
|
||||
|
|
@ -201,8 +209,8 @@ public class JmsListenerAnnotationBeanPostProcessorTests {
|
|||
@Bean
|
||||
public JmsListenerAnnotationBeanPostProcessor postProcessor() {
|
||||
JmsListenerAnnotationBeanPostProcessor postProcessor = new JmsListenerAnnotationBeanPostProcessor();
|
||||
postProcessor.setEndpointRegistry(jmsListenerEndpointRegistry());
|
||||
postProcessor.setContainerFactoryBeanName("testFactory");
|
||||
postProcessor.setEndpointRegistry(jmsListenerEndpointRegistry());
|
||||
return postProcessor;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue