1定时方法所在类,必须有@Component注解,即被spring容器所管理才可以被识别
@Slf4j
@Component
@Async
public class DailyPlayCountSchedule {
@Scheduled(cron = "28 * * * * ?")
// @SchedulerLock(name = "dataHouseKeepingLock", lockAtLeastForString = "PT54S", lockAtMostForString = "PT55S")
public void dataHouseKeepingTest(){
System.out.println(String.format("[%s] DataHouseKeeping job run...", new Date()));
}
}
2 在配置类上增加开启注解
@Configuration
@EnableScheduling
//@EnableSchedulerLock(defaultLockAtMostFor = "PT50M")
public class SchedulerConfig {
}
3 因为定时任务是默认单线程执行的如果多个,会影响其他任务的执行,增加异步配置类,并且在定时任务类上加上注解@Asyn
关于效果我还没有测试
@Configuration
@EnableAsync
public class AsyncConfig {
/*
此处成员变量应该使用@Value从配置中读取
*/
private int corePoolSize = 10;
private int maxPoolSize = 200;
private int queueCapacity = 10;
@Bean
public Executor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(corePoolSize);
executor.setMaxPoolSize(maxPoolSize);
executor.setQueueCapacity(queueCapacity);
executor.initialize();
return executor;
}
}
4 此处定时任务的开启和关闭,是放在注解类上的,如果我们想关闭就必须重新编译代码,那可以放在配置文件中配置吗?
1在application.properties中增加开关,注意这里是重新定义一个bean,所以要支持重写默认bean
com.t.config.scheduler.enabled=false
spring.main.allow-bean-definition-overriding=true
2增加配置类SchedulerCondition,它会去读取配置文件中的开关值来决定是否开启定时
public class SchedulerCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
System.out.println("执行:"+Boolean.valueOf(context.getEnvironment().getProperty("com.t.config.scheduler.enabled")));
return Boolean.valueOf(context.getEnvironment().getProperty("com.ultimate.config.scheduler.enabled"));
}
}
这个配置类的执行与否会根据上面@Conditional中类返回的结果,如果为false则不执行此bean的创建
@Configuration
public class Scheduler {
@Conditional(SchedulerCondition.class)
@Bean(name = TaskManagementConfigUtils.SCHEDULED_ANNOTATION_PROCESSOR_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public ScheduledAnnotationBeanPostProcessor scheduledAnnotationProcessor() {
System.out.println("aaaaaaaaaaaaaaaaaaa");
return new ScheduledAnnotationBeanPostProcessor();
}
}
3 以上为使用定时任务时的操作。我遇到的一个问题是,在mall项目中执行,无论开启还是关闭定时都是始终执行,如果我自动设置的开关为true,则走我的配置,如果我自动配置的开关为false,依然会执行定时任务;而在项目common中就不会这样。
后来经过反复多次测试,发现mall项目在启动类上多了个注解
@EnableRedisHttpSession
这个注解是默认开启了定时,即包含了@EnableScheduling的!!!这样的话,redis是需要开启的,没有办法单独剥离出定时部分,且这两部分,如果我强制关闭,是否会影响到其他部分就不知道了。所以最后我决定,针对我的定时任务,单独增加一个开关,只用来控制,进入某个定时任务后,是否执行
关于格式参考
https://blog.csdn.net/u010331823/article/details/78688232