import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor;
import org.springframework.scheduling.config.ScheduledTask;
import org.springframework.scheduling.config.Task;
import org.springframework.scheduling.support.ScheduledMethodRunnable;
import java.util.HashSet;
import java.util.Set;
/**
* 排除所有的定时任务,当本地工程启动的时候终止所有的定时任务
* 这里使用了ApplicationRunner,为什么用这个接口
* 是因为定时任务的task写入ScheduledTask这个类的时候,是等spring启动完了之后才会写进去的
* 我试了@PostConstruct,InitializingBean等,发现都写不进去
* 所以这里需要注意一些,一定要等springBean都注入完,然后加载完了再对定时任务做特殊处理
*/
@Configuration
@Slf4j
public class ExcludeAllScheduledConfig implements ApplicationRunner {
@Autowired
private ScheduledAnnotationBeanPostProcessor postProcessor;
@Override
public void run(ApplicationArguments args) {
log.info("exclude scheduled begin");
try {
// 拿到所有的task
Set<ScheduledTask> scheduledTasks = postProcessor.getScheduledTasks();
log.info("scheduled task size : {}", scheduledTasks.size());
Set<Object> rawTasks = new HashSet<>(scheduledTasks.size());
for (ScheduledTask item : scheduledTasks) {
Task task = item.getTask();
ScheduledMethodRunnable runnable = (ScheduledMethodRunnable) task.getRunnable();
Object taskObject = runnable.getTarget();
// 将task所关联的对象放到Set中(就是带@Scheduled方法的类)
rawTasks.add(taskObject);
}
// 调用postProcessBeforeDestruction()方法,将task移除并cancel
for (Object obj : rawTasks) {
postProcessor.postProcessBeforeDestruction(obj, "scheduledTasks");
}
} catch (Exception e) {
log.error("exclude scheduled error", e);
}
log.info("exclude scheduled end");
}
}
附上源码和本地执行的截图
其他的自己看去吧,源码一大堆我也懒得贴了,解决了问题就行,看源码的好处就是解决问题方便,网上的很多方法都过时了,因为有些spring版本肯定也更新迭代了,执行顺序和框架规则肯定也变了,还是得自己研究下,照抄网上的一些代码,亲测无效
然后里面执行了一堆最后new了个定时任务的Task