Skip to content

Commit 5bd5df3

Browse files
committed
Post-processors consistently ignore ScopedObject/AopInfrastructureBean
Issue: SPR-17166
1 parent b51685b commit 5bd5df3

File tree

3 files changed

+88
-35
lines changed

3 files changed

+88
-35
lines changed

spring-context/src/main/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@ public Set<Scheduled> inspect(Method method) {
327327
if (annotatedMethods.isEmpty()) {
328328
this.nonAnnotatedClasses.add(targetClass);
329329
if (logger.isTraceEnabled()) {
330-
logger.trace("No @Scheduled annotations found on bean class: " + bean.getClass());
330+
logger.trace("No @Scheduled annotations found on bean class: " + targetClass);
331331
}
332332
}
333333
else {

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

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import org.apache.commons.logging.Log;
2929
import org.apache.commons.logging.LogFactory;
3030

31+
import org.springframework.aop.framework.AopInfrastructureBean;
3132
import org.springframework.aop.framework.AopProxyUtils;
3233
import org.springframework.aop.support.AopUtils;
3334
import org.springframework.beans.BeansException;
@@ -96,10 +97,10 @@ public class JmsListenerAnnotationBeanPostProcessor
9697

9798
protected final Log logger = LogFactory.getLog(getClass());
9899

99-
private JmsListenerEndpointRegistry endpointRegistry;
100-
101100
private String containerFactoryBeanName = DEFAULT_JMS_LISTENER_CONTAINER_FACTORY_BEAN_NAME;
102101

102+
private JmsListenerEndpointRegistry endpointRegistry;
103+
103104
private final MessageHandlerMethodFactoryAdapter messageHandlerMethodFactory =
104105
new MessageHandlerMethodFactoryAdapter();
105106

@@ -120,14 +121,6 @@ public int getOrder() {
120121
return LOWEST_PRECEDENCE;
121122
}
122123

123-
/**
124-
* Set the {@link JmsListenerEndpointRegistry} that will hold the created
125-
* endpoint and manage the lifecycle of the related listener container.
126-
*/
127-
public void setEndpointRegistry(JmsListenerEndpointRegistry endpointRegistry) {
128-
this.endpointRegistry = endpointRegistry;
129-
}
130-
131124
/**
132125
* Set the name of the {@link JmsListenerContainerFactory} to use by default.
133126
* <p>If none is specified, "jmsListenerContainerFactory" is assumed to be defined.
@@ -136,6 +129,14 @@ public void setContainerFactoryBeanName(String containerFactoryBeanName) {
136129
this.containerFactoryBeanName = containerFactoryBeanName;
137130
}
138131

132+
/**
133+
* Set the {@link JmsListenerEndpointRegistry} that will hold the created
134+
* endpoint and manage the lifecycle of the related listener container.
135+
*/
136+
public void setEndpointRegistry(JmsListenerEndpointRegistry endpointRegistry) {
137+
this.endpointRegistry = endpointRegistry;
138+
}
139+
139140
/**
140141
* Set the {@link MessageHandlerMethodFactory} to use to configure the message
141142
* listener responsible to serve an endpoint detected by this processor.
@@ -179,6 +180,10 @@ public void afterSingletonsInstantiated() {
179180
}
180181
}
181182

183+
if (this.containerFactoryBeanName != null) {
184+
this.registrar.setContainerFactoryBeanName(this.containerFactoryBeanName);
185+
}
186+
182187
if (this.registrar.getEndpointRegistry() == null) {
183188
// Determine JmsListenerEndpointRegistry bean from the BeanFactory
184189
if (this.endpointRegistry == null) {
@@ -189,9 +194,6 @@ public void afterSingletonsInstantiated() {
189194
this.registrar.setEndpointRegistry(this.endpointRegistry);
190195
}
191196

192-
if (this.containerFactoryBeanName != null) {
193-
this.registrar.setContainerFactoryBeanName(this.containerFactoryBeanName);
194-
}
195197

196198
// Set the custom handler method factory once resolved by the configurer
197199
MessageHandlerMethodFactory handlerMethodFactory = this.registrar.getMessageHandlerMethodFactory();
@@ -215,8 +217,13 @@ public Object postProcessBeforeInitialization(Object bean, String beanName) thro
215217

216218
@Override
217219
public Object postProcessAfterInitialization(final Object bean, String beanName) throws BeansException {
218-
if (!this.nonAnnotatedClasses.contains(bean.getClass())) {
219-
Class<?> targetClass = AopProxyUtils.ultimateTargetClass(bean);
220+
if (bean instanceof AopInfrastructureBean) {
221+
// Ignore AOP infrastructure such as scoped proxies.
222+
return bean;
223+
}
224+
225+
Class<?> targetClass = AopProxyUtils.ultimateTargetClass(bean);
226+
if (!this.nonAnnotatedClasses.contains(targetClass)) {
220227
Map<Method, Set<JmsListener>> annotatedMethods = MethodIntrospector.selectMethods(targetClass,
221228
new MethodIntrospector.MetadataLookup<Set<JmsListener>>() {
222229
@Override
@@ -227,9 +234,9 @@ public Set<JmsListener> inspect(Method method) {
227234
}
228235
});
229236
if (annotatedMethods.isEmpty()) {
230-
this.nonAnnotatedClasses.add(bean.getClass());
237+
this.nonAnnotatedClasses.add(targetClass);
231238
if (logger.isTraceEnabled()) {
232-
logger.trace("No @JmsListener annotations found on bean type: " + bean.getClass());
239+
logger.trace("No @JmsListener annotations found on bean type: " + targetClass);
233240
}
234241
}
235242
else {

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

Lines changed: 63 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2016 the original author or authors.
2+
* Copyright 2002-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -39,6 +39,7 @@
3939
import org.springframework.jms.config.MessageListenerTestContainer;
4040
import org.springframework.jms.config.MethodJmsListenerEndpoint;
4141
import org.springframework.jms.listener.SimpleMessageListenerContainer;
42+
import org.springframework.messaging.handler.annotation.Header;
4243
import org.springframework.messaging.handler.annotation.SendTo;
4344
import org.springframework.stereotype.Component;
4445
import org.springframework.transaction.PlatformTransactionManager;
@@ -73,8 +74,10 @@ public void simpleMessageListener() throws Exception {
7374
assertEquals("Wrong endpoint type", MethodJmsListenerEndpoint.class, endpoint.getClass());
7475
MethodJmsListenerEndpoint methodEndpoint = (MethodJmsListenerEndpoint) endpoint;
7576
assertEquals(SimpleMessageListenerTestBean.class, methodEndpoint.getBean().getClass());
76-
assertEquals(SimpleMessageListenerTestBean.class.getMethod("handleIt", String.class), methodEndpoint.getMethod());
77-
assertEquals(SimpleMessageListenerTestBean.class.getMethod("handleIt", String.class), methodEndpoint.getMostSpecificMethod());
77+
assertEquals(SimpleMessageListenerTestBean.class.getMethod("handleIt", String.class),
78+
methodEndpoint.getMethod());
79+
assertEquals(SimpleMessageListenerTestBean.class.getMethod("handleIt", String.class),
80+
methodEndpoint.getMostSpecificMethod());
7881

7982
SimpleMessageListenerContainer listenerContainer = new SimpleMessageListenerContainer();
8083
methodEndpoint.setupListenerContainer(listenerContainer);
@@ -98,8 +101,10 @@ public void metaAnnotationIsDiscovered() throws Exception {
98101
assertEquals("Wrong endpoint type", MethodJmsListenerEndpoint.class, endpoint.getClass());
99102
MethodJmsListenerEndpoint methodEndpoint = (MethodJmsListenerEndpoint) endpoint;
100103
assertEquals(MetaAnnotationTestBean.class, methodEndpoint.getBean().getClass());
101-
assertEquals(MetaAnnotationTestBean.class.getMethod("handleIt", String.class), methodEndpoint.getMethod());
102-
assertEquals(MetaAnnotationTestBean.class.getMethod("handleIt", String.class), methodEndpoint.getMostSpecificMethod());
104+
assertEquals(MetaAnnotationTestBean.class.getMethod("handleIt", String.class),
105+
methodEndpoint.getMethod());
106+
assertEquals(MetaAnnotationTestBean.class.getMethod("handleIt", String.class),
107+
methodEndpoint.getMostSpecificMethod());
103108
assertEquals("metaTestQueue", ((AbstractJmsListenerEndpoint) endpoint).getDestination());
104109
}
105110
finally {
@@ -108,9 +113,9 @@ public void metaAnnotationIsDiscovered() throws Exception {
108113
}
109114

110115
@Test
111-
public void sendToAnnotationFoundOnProxy() throws Exception {
116+
public void sendToAnnotationFoundOnInterfaceProxy() throws Exception {
112117
ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(
113-
Config.class, ProxyConfig.class, ProxyTestBean.class);
118+
Config.class, ProxyConfig.class, InterfaceProxyTestBean.class);
114119
try {
115120
JmsListenerContainerTestFactory factory = context.getBean(JmsListenerContainerTestFactory.class);
116121
assertEquals("one container should have been registered", 1, factory.getListenerContainers().size());
@@ -120,12 +125,42 @@ public void sendToAnnotationFoundOnProxy() throws Exception {
120125
MethodJmsListenerEndpoint methodEndpoint = (MethodJmsListenerEndpoint) endpoint;
121126
assertTrue(AopUtils.isJdkDynamicProxy(methodEndpoint.getBean()));
122127
assertTrue(methodEndpoint.getBean() instanceof SimpleService);
123-
assertEquals(SimpleService.class.getMethod("handleIt", String.class), methodEndpoint.getMethod());
124-
assertEquals(ProxyTestBean.class.getMethod("handleIt", String.class), methodEndpoint.getMostSpecificMethod());
128+
assertEquals(SimpleService.class.getMethod("handleIt", String.class, String.class),
129+
methodEndpoint.getMethod());
130+
assertEquals(InterfaceProxyTestBean.class.getMethod("handleIt", String.class, String.class),
131+
methodEndpoint.getMostSpecificMethod());
132+
133+
Method method = ReflectionUtils.findMethod(endpoint.getClass(), "getDefaultResponseDestination");
134+
ReflectionUtils.makeAccessible(method);
135+
Object destination = ReflectionUtils.invokeMethod(method, endpoint);
136+
assertEquals("SendTo annotation not found on proxy", "foobar", destination);
137+
}
138+
finally {
139+
context.close();
140+
}
141+
}
142+
143+
@Test
144+
public void sendToAnnotationFoundOnCglibProxy() throws Exception {
145+
ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(
146+
Config.class, ProxyConfig.class, ClassProxyTestBean.class);
147+
try {
148+
JmsListenerContainerTestFactory factory = context.getBean(JmsListenerContainerTestFactory.class);
149+
assertEquals("one container should have been registered", 1, factory.getListenerContainers().size());
125150

126-
Method m = ReflectionUtils.findMethod(endpoint.getClass(), "getDefaultResponseDestination");
127-
ReflectionUtils.makeAccessible(m);
128-
Object destination = ReflectionUtils.invokeMethod(m, endpoint);
151+
JmsListenerEndpoint endpoint = factory.getListenerContainers().get(0).getEndpoint();
152+
assertEquals("Wrong endpoint type", MethodJmsListenerEndpoint.class, endpoint.getClass());
153+
MethodJmsListenerEndpoint methodEndpoint = (MethodJmsListenerEndpoint) endpoint;
154+
assertTrue(AopUtils.isCglibProxy(methodEndpoint.getBean()));
155+
assertTrue(methodEndpoint.getBean() instanceof ClassProxyTestBean);
156+
assertEquals(ClassProxyTestBean.class.getMethod("handleIt", String.class, String.class),
157+
methodEndpoint.getMethod());
158+
assertEquals(ClassProxyTestBean.class.getMethod("handleIt", String.class, String.class),
159+
methodEndpoint.getMostSpecificMethod());
160+
161+
Method method = ReflectionUtils.findMethod(endpoint.getClass(), "getDefaultResponseDestination");
162+
ReflectionUtils.makeAccessible(method);
163+
Object destination = ReflectionUtils.invokeMethod(method, endpoint);
129164
assertEquals("SendTo annotation not found on proxy", "foobar", destination);
130165
}
131166
finally {
@@ -174,8 +209,8 @@ static class Config {
174209
@Bean
175210
public JmsListenerAnnotationBeanPostProcessor postProcessor() {
176211
JmsListenerAnnotationBeanPostProcessor postProcessor = new JmsListenerAnnotationBeanPostProcessor();
177-
postProcessor.setEndpointRegistry(jmsListenerEndpointRegistry());
178212
postProcessor.setContainerFactoryBeanName("testFactory");
213+
postProcessor.setEndpointRegistry(jmsListenerEndpointRegistry());
179214
return postProcessor;
180215
}
181216

@@ -204,18 +239,29 @@ public PlatformTransactionManager transactionManager() {
204239

205240
interface SimpleService {
206241

207-
void handleIt(String body);
242+
void handleIt(String value, String body);
208243
}
209244

210245

211246
@Component
212-
static class ProxyTestBean implements SimpleService {
247+
static class InterfaceProxyTestBean implements SimpleService {
213248

214249
@Override
215250
@Transactional
216251
@JmsListener(destination = "testQueue")
217252
@SendTo("foobar")
218-
public void handleIt(String body) {
253+
public void handleIt(@Header String value, String body) {
254+
}
255+
}
256+
257+
258+
@Component
259+
static class ClassProxyTestBean {
260+
261+
@Transactional
262+
@JmsListener(destination = "testQueue")
263+
@SendTo("foobar")
264+
public void handleIt(@Header String value, String body) {
219265
}
220266
}
221267

@@ -224,7 +270,7 @@ public void handleIt(String body) {
224270
static class InvalidProxyTestBean implements SimpleService {
225271

226272
@Override
227-
public void handleIt(String body) {
273+
public void handleIt(String value, String body) {
228274
}
229275

230276
@Transactional

0 commit comments

Comments
 (0)