28
28
import org .apache .commons .logging .Log ;
29
29
import org .apache .commons .logging .LogFactory ;
30
30
31
- import org .springframework .aop .SpringProxy ;
32
31
import org .springframework .aop .scope .ScopedProxyUtils ;
33
- import org .springframework .aop .support .AopUtils ;
34
32
import org .springframework .beans .BeansException ;
35
33
import org .springframework .beans .factory .BeanInitializationException ;
36
34
import org .springframework .beans .factory .SmartInitializingSingleton ;
48
46
* instances.
49
47
*
50
48
* @author Stephane Nicoll
49
+ * @author Juergen Hoeller
51
50
* @since 4.2
52
51
*/
53
52
public class EventListenerMethodProcessor implements SmartInitializingSingleton , ApplicationContextAware {
@@ -61,6 +60,7 @@ public class EventListenerMethodProcessor implements SmartInitializingSingleton,
61
60
private final Set <Class <?>> nonAnnotatedClasses =
62
61
Collections .newSetFromMap (new ConcurrentHashMap <Class <?>, Boolean >(64 ));
63
62
63
+
64
64
@ Override
65
65
public void setApplicationContext (ApplicationContext applicationContext ) throws BeansException {
66
66
Assert .isTrue (applicationContext instanceof ConfigurableApplicationContext ,
@@ -69,18 +69,6 @@ public void setApplicationContext(ApplicationContext applicationContext) throws
69
69
70
70
}
71
71
72
- /**
73
- * Return the {@link EventListenerFactory} instances to use to handle {@link EventListener}
74
- * annotated methods.
75
- */
76
- protected List <EventListenerFactory > getEventListenerFactories () {
77
- Map <String , EventListenerFactory > beans =
78
- this .applicationContext .getBeansOfType (EventListenerFactory .class );
79
- List <EventListenerFactory > allFactories = new ArrayList <EventListenerFactory >(beans .values ());
80
- AnnotationAwareOrderComparator .sort (allFactories );
81
- return allFactories ;
82
- }
83
-
84
72
@ Override
85
73
public void afterSingletonsInstantiated () {
86
74
List <EventListenerFactory > factories = getEventListenerFactories ();
@@ -91,16 +79,27 @@ public void afterSingletonsInstantiated() {
91
79
try {
92
80
processBean (factories , beanName , type );
93
81
}
94
- catch (RuntimeException e ) {
82
+ catch (Throwable ex ) {
95
83
throw new BeanInitializationException ("Failed to process @EventListener " +
96
- "annotation on bean with name '" + beanName + "'" , e );
84
+ "annotation on bean with name '" + beanName + "'" , ex );
97
85
}
98
86
}
99
87
}
100
88
}
101
89
102
- protected void processBean (List <EventListenerFactory > factories , String beanName , final Class <?> type ) {
103
- Class <?> targetType = getTargetClass (beanName , type );
90
+ /**
91
+ * Return the {@link EventListenerFactory} instances to use to handle {@link EventListener}
92
+ * annotated methods.
93
+ */
94
+ protected List <EventListenerFactory > getEventListenerFactories () {
95
+ Map <String , EventListenerFactory > beans =
96
+ this .applicationContext .getBeansOfType (EventListenerFactory .class );
97
+ List <EventListenerFactory > allFactories = new ArrayList <EventListenerFactory >(beans .values ());
98
+ AnnotationAwareOrderComparator .sort (allFactories );
99
+ return allFactories ;
100
+ }
101
+
102
+ protected void processBean (List <EventListenerFactory > factories , String beanName , final Class <?> targetType ) {
104
103
if (!this .nonAnnotatedClasses .contains (targetType )) {
105
104
final Set <Method > annotatedMethods = new LinkedHashSet <Method >(1 );
106
105
Method [] methods = ReflectionUtils .getUniqueDeclaredMethods (targetType );
@@ -111,13 +110,10 @@ protected void processBean(List<EventListenerFactory> factories, String beanName
111
110
}
112
111
for (EventListenerFactory factory : factories ) {
113
112
if (factory .supportsMethod (method )) {
114
- if (!type .equals (targetType )) {
115
- method = getProxyMethod (type , method );
116
- }
117
113
ApplicationListener <?> applicationListener =
118
- factory .createApplicationListener (beanName , type , method );
114
+ factory .createApplicationListener (beanName , targetType , method );
119
115
if (applicationListener instanceof ApplicationListenerMethodAdapter ) {
120
- ((ApplicationListenerMethodAdapter )applicationListener )
116
+ ((ApplicationListenerMethodAdapter ) applicationListener )
121
117
.init (this .applicationContext , this .evaluator );
122
118
}
123
119
this .applicationContext .addApplicationListener (applicationListener );
@@ -127,49 +123,19 @@ protected void processBean(List<EventListenerFactory> factories, String beanName
127
123
}
128
124
}
129
125
if (annotatedMethods .isEmpty ()) {
130
- this .nonAnnotatedClasses .add (type );
126
+ this .nonAnnotatedClasses .add (targetType );
131
127
if (logger .isTraceEnabled ()) {
132
- logger .trace ("No @EventListener annotations found on bean class: " + type );
128
+ logger .trace ("No @EventListener annotations found on bean class: " + targetType );
133
129
}
134
130
}
135
131
else {
136
132
// Non-empty set of methods
137
133
if (logger .isDebugEnabled ()) {
138
- logger .debug (annotatedMethods .size () + " @EventListener methods processed on bean '" + beanName +
139
- "': " + annotatedMethods );
134
+ logger .debug (annotatedMethods .size () + " @EventListener methods processed on bean '" +
135
+ beanName + "': " + annotatedMethods );
140
136
}
141
137
}
142
138
}
143
139
}
144
140
145
- private Class <?> getTargetClass (String beanName , Class <?> type ) {
146
- if (SpringProxy .class .isAssignableFrom (type )) {
147
- Object bean = this .applicationContext .getBean (beanName );
148
- return AopUtils .getTargetClass (bean );
149
- }
150
- else {
151
- return type ;
152
- }
153
- }
154
-
155
- private Method getProxyMethod (Class <?> proxyType , Method method ) {
156
- try {
157
- // Found a @EventListener method on the target class for this JDK proxy ->
158
- // is it also present on the proxy itself?
159
- return proxyType .getMethod (method .getName (), method .getParameterTypes ());
160
- }
161
- catch (SecurityException ex ) {
162
- ReflectionUtils .handleReflectionException (ex );
163
- }
164
- catch (NoSuchMethodException ex ) {
165
- throw new IllegalStateException (String .format (
166
- "@EventListener method '%s' found on bean target class '%s', " +
167
- "but not found in any interface(s) for bean JDK proxy. Either " +
168
- "pull the method up to an interface or switch to subclass (CGLIB) " +
169
- "proxies by setting proxy-target-class/proxyTargetClass " +
170
- "attribute to 'true'" , method .getName (), method .getDeclaringClass ().getSimpleName ()));
171
- }
172
- return null ;
173
- }
174
-
175
141
}
0 commit comments