diff --git a/spring-context/src/main/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessor.java b/spring-context/src/main/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessor.java index 6185443c2b2..d435e6eb42e 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessor.java +++ b/spring-context/src/main/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessor.java @@ -17,9 +17,13 @@ package org.springframework.scheduling.annotation; import java.lang.reflect.Method; +import java.util.Collections; import java.util.HashMap; +import java.util.LinkedHashSet; import java.util.Map; +import java.util.Set; import java.util.TimeZone; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ScheduledExecutorService; import org.springframework.aop.support.AopUtils; @@ -81,6 +85,9 @@ public class ScheduledAnnotationBeanPostProcessor private final ScheduledTaskRegistrar registrar = new ScheduledTaskRegistrar(); + private final Set> nonAnnotatedClasses = + Collections.newSetFromMap(new ConcurrentHashMap, Boolean>(64)); + @Override public int getOrder() { @@ -134,12 +141,11 @@ public class ScheduledAnnotationBeanPostProcessor this.registrar.setScheduler(schedulers.values().iterator().next()); } else if (schedulers.size() >= 2){ - throw new IllegalStateException( - "More than one TaskScheduler and/or ScheduledExecutorService " + - "exist within the context. Remove all but one of the beans; or " + - "implement the SchedulingConfigurer interface and call " + - "ScheduledTaskRegistrar#setScheduler explicitly within the " + - "configureTasks() callback. Found the following beans: " + schedulers.keySet()); + throw new IllegalStateException("More than one TaskScheduler and/or ScheduledExecutorService " + + "exist within the context. Remove all but one of the beans; or implement the " + + "SchedulingConfigurer interface and call ScheduledTaskRegistrar#setScheduler " + + "explicitly within the configureTasks() callback. Found the following beans: " + + schedulers.keySet()); } } @@ -154,15 +160,23 @@ public class ScheduledAnnotationBeanPostProcessor @Override public Object postProcessAfterInitialization(final Object bean, String beanName) { - Class targetClass = AopUtils.getTargetClass(bean); - ReflectionUtils.doWithMethods(targetClass, new MethodCallback() { - @Override - public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException { - for (Scheduled scheduled : AnnotationUtils.getRepeatableAnnotation(method, Schedules.class, Scheduled.class)) { - processScheduled(scheduled, method, bean); + if (!this.nonAnnotatedClasses.contains(bean.getClass())) { + final Set annotatedMethods = new LinkedHashSet(1); + Class targetClass = AopUtils.getTargetClass(bean); + ReflectionUtils.doWithMethods(targetClass, new MethodCallback() { + @Override + public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException { + for (Scheduled scheduled : + AnnotationUtils.getRepeatableAnnotation(method, Schedules.class, Scheduled.class)) { + processScheduled(scheduled, method, bean); + annotatedMethods.add(method); + } } + }); + if (annotatedMethods.isEmpty()) { + this.nonAnnotatedClasses.add(bean.getClass()); } - }); + } return bean; }