18
18
19
19
import java .lang .reflect .Method ;
20
20
import java .util .Collections ;
21
- import java .util .LinkedHashSet ;
22
21
import java .util .Map ;
23
22
import java .util .Set ;
24
23
import java .util .concurrent .ConcurrentHashMap ;
37
36
import org .springframework .beans .factory .SmartInitializingSingleton ;
38
37
import org .springframework .beans .factory .config .BeanPostProcessor ;
39
38
import org .springframework .beans .factory .config .ConfigurableBeanFactory ;
39
+ import org .springframework .core .MethodIntrospector ;
40
40
import org .springframework .core .Ordered ;
41
41
import org .springframework .core .annotation .AnnotationUtils ;
42
42
import org .springframework .jms .config .JmsListenerConfigUtils ;
48
48
import org .springframework .messaging .handler .annotation .support .MessageHandlerMethodFactory ;
49
49
import org .springframework .messaging .handler .invocation .InvocableHandlerMethod ;
50
50
import org .springframework .util .Assert ;
51
- import org .springframework .util .ReflectionUtils ;
52
51
import org .springframework .util .StringUtils ;
53
52
54
53
/**
@@ -194,26 +193,30 @@ public Object postProcessBeforeInitialization(Object bean, String beanName) thro
194
193
@ Override
195
194
public Object postProcessAfterInitialization (final Object bean , String beanName ) throws BeansException {
196
195
if (!this .nonAnnotatedClasses .contains (bean .getClass ())) {
197
- final Set <Method > annotatedMethods = new LinkedHashSet <Method >(1 );
198
196
Class <?> targetClass = AopUtils .getTargetClass (bean );
199
- ReflectionUtils .doWithMethods (targetClass , new ReflectionUtils .MethodCallback () {
200
- @ Override
201
- public void doWith (Method method ) throws IllegalArgumentException , IllegalAccessException {
202
- for (JmsListener jmsListener :
203
- AnnotationUtils .getRepeatableAnnotations (method , JmsListener .class , JmsListeners .class )) {
204
- processJmsListener (jmsListener , method , bean );
205
- annotatedMethods .add (method );
206
- }
207
- }
208
- });
197
+ Map <Method , Set <JmsListener >> annotatedMethods = MethodIntrospector .selectMethods (targetClass ,
198
+ new MethodIntrospector .MetadataLookup <Set <JmsListener >>() {
199
+ @ Override
200
+ public Set <JmsListener > inspect (Method method ) {
201
+ Set <JmsListener > listenerMethods =
202
+ AnnotationUtils .getRepeatableAnnotations (method , JmsListener .class , JmsListeners .class );
203
+ return (!listenerMethods .isEmpty () ? listenerMethods : null );
204
+ }
205
+ });
209
206
if (annotatedMethods .isEmpty ()) {
210
207
this .nonAnnotatedClasses .add (bean .getClass ());
211
208
if (logger .isTraceEnabled ()) {
212
- logger .trace ("No @JmsListener annotations found on bean class : " + bean .getClass ());
209
+ logger .trace ("No @JmsListener annotations found on bean type : " + bean .getClass ());
213
210
}
214
211
}
215
212
else {
216
213
// Non-empty set of methods
214
+ for (Map .Entry <Method , Set <JmsListener >> entry : annotatedMethods .entrySet ()) {
215
+ Method method = entry .getKey ();
216
+ for (JmsListener listener : entry .getValue ()) {
217
+ processJmsListener (listener , method , bean );
218
+ }
219
+ }
217
220
if (logger .isDebugEnabled ()) {
218
221
logger .debug (annotatedMethods .size () + " @JmsListener methods processed on bean '" + beanName +
219
222
"': " + annotatedMethods );
@@ -223,29 +226,13 @@ public void doWith(Method method) throws IllegalArgumentException, IllegalAccess
223
226
return bean ;
224
227
}
225
228
226
- protected void processJmsListener (JmsListener jmsListener , Method method , Object bean ) {
227
- if (AopUtils .isJdkDynamicProxy (bean )) {
228
- try {
229
- // Found a @JmsListener method on the target class for this JDK proxy ->
230
- // is it also present on the proxy itself?
231
- method = bean .getClass ().getMethod (method .getName (), method .getParameterTypes ());
232
- }
233
- catch (SecurityException ex ) {
234
- ReflectionUtils .handleReflectionException (ex );
235
- }
236
- catch (NoSuchMethodException ex ) {
237
- throw new IllegalStateException (String .format (
238
- "@JmsListener method '%s' found on bean target class '%s', " +
239
- "but not found in any interface(s) for bean JDK proxy. Either " +
240
- "pull the method up to an interface or switch to subclass (CGLIB) " +
241
- "proxies by setting proxy-target-class/proxyTargetClass " +
242
- "attribute to 'true'" , method .getName (), method .getDeclaringClass ().getSimpleName ()));
243
- }
244
- }
229
+ protected void processJmsListener (JmsListener jmsListener , Method mostSpecificMethod , Object bean ) {
230
+ Method invocableMethod = MethodIntrospector .selectInvocableMethod (mostSpecificMethod , bean .getClass ());
245
231
246
232
MethodJmsListenerEndpoint endpoint = new MethodJmsListenerEndpoint ();
247
233
endpoint .setBean (bean );
248
- endpoint .setMethod (method );
234
+ endpoint .setMethod (invocableMethod );
235
+ endpoint .setMostSpecificMethod (mostSpecificMethod );
249
236
endpoint .setMessageHandlerMethodFactory (this .messageHandlerMethodFactory );
250
237
endpoint .setBeanFactory (this .beanFactory );
251
238
endpoint .setId (getEndpointId (jmsListener ));
@@ -268,9 +255,9 @@ protected void processJmsListener(JmsListener jmsListener, Method method, Object
268
255
factory = this .beanFactory .getBean (containerFactoryBeanName , JmsListenerContainerFactory .class );
269
256
}
270
257
catch (NoSuchBeanDefinitionException ex ) {
271
- throw new BeanInitializationException ("Could not register jms listener endpoint on [" +
272
- method + "], no " + JmsListenerContainerFactory .class .getSimpleName () + " with id '" +
273
- containerFactoryBeanName + "' was found in the application context" , ex );
258
+ throw new BeanInitializationException ("Could not register JMS listener endpoint on [" +
259
+ mostSpecificMethod + "], no " + JmsListenerContainerFactory .class .getSimpleName () +
260
+ " with id '" + containerFactoryBeanName + "' was found in the application context" , ex );
274
261
}
275
262
}
276
263
0 commit comments