17
17
package org .springframework .scheduling .annotation ;
18
18
19
19
import java .lang .reflect .Method ;
20
+ import java .util .Collections ;
20
21
import java .util .HashMap ;
22
+ import java .util .LinkedHashSet ;
21
23
import java .util .Map ;
24
+ import java .util .Set ;
22
25
import java .util .TimeZone ;
26
+ import java .util .concurrent .ConcurrentHashMap ;
23
27
import java .util .concurrent .ScheduledExecutorService ;
24
28
29
+ import org .apache .commons .logging .Log ;
30
+ import org .apache .commons .logging .LogFactory ;
31
+
25
32
import org .springframework .aop .support .AopUtils ;
26
33
import org .springframework .beans .factory .BeanFactory ;
27
34
import org .springframework .beans .factory .BeanFactoryAware ;
@@ -74,6 +81,8 @@ public class ScheduledAnnotationBeanPostProcessor
74
81
implements BeanPostProcessor , Ordered , EmbeddedValueResolverAware , BeanFactoryAware ,
75
82
SmartInitializingSingleton , DisposableBean {
76
83
84
+ protected final Log logger = LogFactory .getLog (getClass ());
85
+
77
86
private Object scheduler ;
78
87
79
88
private StringValueResolver embeddedValueResolver ;
@@ -82,6 +91,9 @@ public class ScheduledAnnotationBeanPostProcessor
82
91
83
92
private final ScheduledTaskRegistrar registrar = new ScheduledTaskRegistrar ();
84
93
94
+ private final Set <Class <?>> nonAnnotatedClasses =
95
+ Collections .newSetFromMap (new ConcurrentHashMap <Class <?>, Boolean >(64 ));
96
+
85
97
86
98
@ Override
87
99
public int getOrder () {
@@ -117,7 +129,9 @@ public void setBeanFactory(BeanFactory beanFactory) {
117
129
*/
118
130
@ Deprecated
119
131
public void setApplicationContext (ApplicationContext applicationContext ) {
120
- this .beanFactory = applicationContext ;
132
+ if (this .beanFactory == null ) {
133
+ this .beanFactory = applicationContext ;
134
+ }
121
135
}
122
136
123
137
@@ -146,12 +160,11 @@ else if (schedulers.size() == 1) {
146
160
this .registrar .setScheduler (schedulers .values ().iterator ().next ());
147
161
}
148
162
else if (schedulers .size () >= 2 ){
149
- throw new IllegalStateException (
150
- "More than one TaskScheduler and/or ScheduledExecutorService " +
151
- "exist within the context. Remove all but one of the beans; or " +
152
- "implement the SchedulingConfigurer interface and call " +
153
- "ScheduledTaskRegistrar#setScheduler explicitly within the " +
154
- "configureTasks() callback. Found the following beans: " + schedulers .keySet ());
163
+ throw new IllegalStateException ("More than one TaskScheduler and/or ScheduledExecutorService " +
164
+ "exist within the context. Remove all but one of the beans; or implement the " +
165
+ "SchedulingConfigurer interface and call ScheduledTaskRegistrar#setScheduler " +
166
+ "explicitly within the configureTasks() callback. Found the following beans: " +
167
+ schedulers .keySet ());
155
168
}
156
169
}
157
170
@@ -166,15 +179,33 @@ public Object postProcessBeforeInitialization(Object bean, String beanName) {
166
179
167
180
@ Override
168
181
public Object postProcessAfterInitialization (final Object bean , String beanName ) {
169
- Class <?> targetClass = AopUtils .getTargetClass (bean );
170
- ReflectionUtils .doWithMethods (targetClass , new MethodCallback () {
171
- @ Override
172
- public void doWith (Method method ) throws IllegalArgumentException , IllegalAccessException {
173
- for (Scheduled scheduled : AnnotationUtils .getRepeatableAnnotation (method , Schedules .class , Scheduled .class )) {
174
- processScheduled (scheduled , method , bean );
182
+ if (!this .nonAnnotatedClasses .contains (bean .getClass ())) {
183
+ final Set <Method > annotatedMethods = new LinkedHashSet <Method >(1 );
184
+ Class <?> targetClass = AopUtils .getTargetClass (bean );
185
+ ReflectionUtils .doWithMethods (targetClass , new MethodCallback () {
186
+ @ Override
187
+ public void doWith (Method method ) throws IllegalArgumentException , IllegalAccessException {
188
+ for (Scheduled scheduled :
189
+ AnnotationUtils .getRepeatableAnnotation (method , Schedules .class , Scheduled .class )) {
190
+ processScheduled (scheduled , method , bean );
191
+ annotatedMethods .add (method );
192
+ }
193
+ }
194
+ });
195
+ if (annotatedMethods .isEmpty ()) {
196
+ this .nonAnnotatedClasses .add (bean .getClass ());
197
+ if (logger .isDebugEnabled ()) {
198
+ logger .debug ("No @Scheduled annotations found on bean class: " + bean .getClass ());
199
+ }
200
+ }
201
+ else {
202
+ // Non-empty set of methods
203
+ if (logger .isDebugEnabled ()) {
204
+ logger .debug (annotatedMethods .size () + " @Scheduled methods processed on bean '" + beanName +
205
+ "': " + annotatedMethods );
175
206
}
176
207
}
177
- });
208
+ }
178
209
return bean ;
179
210
}
180
211
0 commit comments