1818
1919import java .lang .reflect .Method ;
2020import java .util .Collections ;
21- import java .util .LinkedHashSet ;
2221import java .util .Map ;
2322import java .util .Set ;
2423import java .util .concurrent .ConcurrentHashMap ;
3736import org .springframework .beans .factory .SmartInitializingSingleton ;
3837import org .springframework .beans .factory .config .BeanPostProcessor ;
3938import org .springframework .beans .factory .config .ConfigurableBeanFactory ;
39+ import org .springframework .core .MethodIntrospector ;
4040import org .springframework .core .Ordered ;
4141import org .springframework .core .annotation .AnnotationUtils ;
4242import org .springframework .jms .config .JmsListenerConfigUtils ;
4848import org .springframework .messaging .handler .annotation .support .MessageHandlerMethodFactory ;
4949import org .springframework .messaging .handler .invocation .InvocableHandlerMethod ;
5050import org .springframework .util .Assert ;
51- import org .springframework .util .ReflectionUtils ;
5251import org .springframework .util .StringUtils ;
5352
5453/**
@@ -194,26 +193,30 @@ public Object postProcessBeforeInitialization(Object bean, String beanName) thro
194193 @ Override
195194 public Object postProcessAfterInitialization (final Object bean , String beanName ) throws BeansException {
196195 if (!this .nonAnnotatedClasses .contains (bean .getClass ())) {
197- final Set <Method > annotatedMethods = new LinkedHashSet <Method >(1 );
198196 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+ });
209206 if (annotatedMethods .isEmpty ()) {
210207 this .nonAnnotatedClasses .add (bean .getClass ());
211208 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 ());
213210 }
214211 }
215212 else {
216213 // 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+ }
217220 if (logger .isDebugEnabled ()) {
218221 logger .debug (annotatedMethods .size () + " @JmsListener methods processed on bean '" + beanName +
219222 "': " + annotatedMethods );
@@ -223,29 +226,13 @@ public void doWith(Method method) throws IllegalArgumentException, IllegalAccess
223226 return bean ;
224227 }
225228
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 ());
245231
246232 MethodJmsListenerEndpoint endpoint = new MethodJmsListenerEndpoint ();
247233 endpoint .setBean (bean );
248- endpoint .setMethod (method );
234+ endpoint .setMethod (invocableMethod );
235+ endpoint .setMostSpecificMethod (mostSpecificMethod );
249236 endpoint .setMessageHandlerMethodFactory (this .messageHandlerMethodFactory );
250237 endpoint .setBeanFactory (this .beanFactory );
251238 endpoint .setId (getEndpointId (jmsListener ));
@@ -268,9 +255,9 @@ protected void processJmsListener(JmsListener jmsListener, Method method, Object
268255 factory = this .beanFactory .getBean (containerFactoryBeanName , JmsListenerContainerFactory .class );
269256 }
270257 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 );
274261 }
275262 }
276263
0 commit comments