1717package org .springframework .scheduling .annotation ;
1818
1919import java .lang .reflect .Method ;
20+ import java .util .Collections ;
2021import java .util .HashMap ;
22+ import java .util .LinkedHashSet ;
2123import java .util .Map ;
24+ import java .util .Set ;
2225import java .util .TimeZone ;
26+ import java .util .concurrent .ConcurrentHashMap ;
2327import java .util .concurrent .ScheduledExecutorService ;
2428
29+ import org .apache .commons .logging .Log ;
30+ import org .apache .commons .logging .LogFactory ;
31+
2532import org .springframework .aop .support .AopUtils ;
2633import org .springframework .beans .factory .BeanFactory ;
2734import org .springframework .beans .factory .BeanFactoryAware ;
@@ -74,6 +81,8 @@ public class ScheduledAnnotationBeanPostProcessor
7481 implements BeanPostProcessor , Ordered , EmbeddedValueResolverAware , BeanFactoryAware ,
7582 SmartInitializingSingleton , DisposableBean {
7683
84+ protected final Log logger = LogFactory .getLog (getClass ());
85+
7786 private Object scheduler ;
7887
7988 private StringValueResolver embeddedValueResolver ;
@@ -82,6 +91,9 @@ public class ScheduledAnnotationBeanPostProcessor
8291
8392 private final ScheduledTaskRegistrar registrar = new ScheduledTaskRegistrar ();
8493
94+ private final Set <Class <?>> nonAnnotatedClasses =
95+ Collections .newSetFromMap (new ConcurrentHashMap <Class <?>, Boolean >(64 ));
96+
8597
8698 @ Override
8799 public int getOrder () {
@@ -117,7 +129,9 @@ public void setBeanFactory(BeanFactory beanFactory) {
117129 */
118130 @ Deprecated
119131 public void setApplicationContext (ApplicationContext applicationContext ) {
120- this .beanFactory = applicationContext ;
132+ if (this .beanFactory == null ) {
133+ this .beanFactory = applicationContext ;
134+ }
121135 }
122136
123137
@@ -146,12 +160,11 @@ else if (schedulers.size() == 1) {
146160 this .registrar .setScheduler (schedulers .values ().iterator ().next ());
147161 }
148162 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 ());
155168 }
156169 }
157170
@@ -166,15 +179,33 @@ public Object postProcessBeforeInitialization(Object bean, String beanName) {
166179
167180 @ Override
168181 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 );
175206 }
176207 }
177- });
208+ }
178209 return bean ;
179210 }
180211
0 commit comments