|
|
|
|
@ -17,6 +17,7 @@
@@ -17,6 +17,7 @@
|
|
|
|
|
package org.springframework.scheduling.annotation; |
|
|
|
|
|
|
|
|
|
import java.lang.reflect.Method; |
|
|
|
|
import java.lang.reflect.Modifier; |
|
|
|
|
import java.util.HashMap; |
|
|
|
|
import java.util.LinkedHashSet; |
|
|
|
|
import java.util.Map; |
|
|
|
|
@ -24,6 +25,8 @@ import java.util.Set;
@@ -24,6 +25,8 @@ import java.util.Set;
|
|
|
|
|
import java.util.concurrent.ConcurrentHashMap; |
|
|
|
|
import java.util.concurrent.ScheduledExecutorService; |
|
|
|
|
|
|
|
|
|
import org.apache.commons.logging.LogFactory; |
|
|
|
|
|
|
|
|
|
import org.springframework.aop.support.AopUtils; |
|
|
|
|
import org.springframework.beans.factory.DisposableBean; |
|
|
|
|
import org.springframework.beans.factory.config.BeanPostProcessor; |
|
|
|
|
@ -188,17 +191,27 @@ public class ScheduledAnnotationBeanPostProcessor
@@ -188,17 +191,27 @@ public class ScheduledAnnotationBeanPostProcessor
|
|
|
|
|
} |
|
|
|
|
catch (NoSuchMethodException ex) { |
|
|
|
|
throw new IllegalStateException(String.format( |
|
|
|
|
"@Scheduled method '%s' found on bean target class '%s', " + |
|
|
|
|
"but not found in any interface(s) for bean JDK proxy. Either " + |
|
|
|
|
"pull the method up to an interface or switch to subclass (CGLIB) " + |
|
|
|
|
"proxies by setting proxy-target-class/proxyTargetClass " + |
|
|
|
|
"attribute to 'true'", method.getName(), method.getDeclaringClass().getSimpleName())); |
|
|
|
|
"@Scheduled method '%s' found on bean target class '%s' but not " + |
|
|
|
|
"found in any interface(s) for a dynamic proxy. Either pull the " + |
|
|
|
|
"method up to a declared interface or switch to subclass (CGLIB) " + |
|
|
|
|
"proxies by setting proxy-target-class/proxyTargetClass to 'true'", |
|
|
|
|
method.getName(), method.getDeclaringClass().getSimpleName())); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
else if (AopUtils.isCglibProxy(bean)) { |
|
|
|
|
// Common problem: private methods end up in the proxy instance, not getting delegated.
|
|
|
|
|
if (Modifier.isPrivate(method.getModifiers())) { |
|
|
|
|
LogFactory.getLog(ScheduledAnnotationBeanPostProcessor.class).warn(String.format( |
|
|
|
|
"@Scheduled method '%s' found on CGLIB proxy for target class '%s' but cannot " + |
|
|
|
|
"be delegated to target bean. Switch its visibility to package or protected.", |
|
|
|
|
method.getName(), method.getDeclaringClass().getSimpleName())); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Runnable runnable = new ScheduledMethodRunnable(bean, method); |
|
|
|
|
boolean processedSchedule = false; |
|
|
|
|
String errorMessage = "Exactly one of the 'cron', 'fixedDelay(String)', or 'fixedRate(String)' attributes is required"; |
|
|
|
|
String errorMessage = |
|
|
|
|
"Exactly one of the 'cron', 'fixedDelay(String)', or 'fixedRate(String)' attributes is required"; |
|
|
|
|
|
|
|
|
|
// Determine initial delay
|
|
|
|
|
long initialDelay = scheduled.initialDelay(); |
|
|
|
|
|