GitHub:https://github.com/chenyingjun/springboot2-task
使用 @EnableScheduling 方式
- @Component
- @Configurable
- @EnableScheduling
- public class Task1 {
- private static Log logger = LogFactory.getLog(Task1.class);
- @Scheduled(cron = "0/2 * * * * *")
- public void execute() {
- logger.info("Task1>>" + new Date());
- }
- }
xml 配置方式
application 启动加入读取 xml 文件
- @SpringBootApplication
- @ImportResource(value = { "classpath:applicationContext*.xml" })
- public class Springboot2TaskApplication {
- public static void main(String[] args) {
- SpringApplication.run(Springboot2TaskApplication.class, args);
- }
- }
- <context:component-scan base-package="com.chenyingjun.task.schedual"></context:component-scan>
- <task:scheduler id="appScheduler" pool-size="2" />
- <!-- 调整定时任务 -->
- <task:scheduled-tasks>
- <task:scheduled ref="task2" method="method2" cron="0/10 * * * * ?"/>
- </task:scheduled-tasks>
- @Service
- public class Task2 {
- private static Log logger = LogFactory.getLog(Task2.class);
- public void method2() {
- logger.info("Task2----method2>>>>" + new Date());
- }
- }
bean 创建工厂方式
使用到的 jar 包
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-context-support</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-tx</artifactId>
- </dependency>
- <dependency>
- <groupId>org.quartz-scheduler</groupId>
- <artifactId>quartz</artifactId>
- <version>2.3.0</version>
- </dependency>
新建 SchedledConfiguration.java 文件
- @Configuration
- public class SchedledConfiguration {
- /**
- * attention:
- * Details: 配置定时任务
- */
- @Bean(name = "jobDetail")
- public MethodInvokingJobDetailFactoryBean detailFactoryBean(Task3 task) {// TestTask 为需要执行的任务
- MethodInvokingJobDetailFactoryBean jobDetail = new MethodInvokingJobDetailFactoryBean();
- /*
- * 是否并发执行
- * 例如每 5s 执行一次任务, 但是当前任务还没有执行完, 就已经过了 5s 了,
- * 如果此处为 true, 则下一个任务会执行, 如果此处为 false, 则下一个任务会等待上一个任务执行完后, 再开始执行
- */
- jobDetail.setConcurrent(false);
- // 设置任务的名字
- jobDetail.setName("jobDetailName");
- // 设置任务的分组, 这些属性都可以存储在数据库中, 在多任务的时候使用
- jobDetail.setGroup("jobDetailGroup");
- /*
- * 为需要执行的实体类对应的对象
- */
- jobDetail.setTargetObject(task);
- /*
- * 通过这几个配置, 告诉 JobDetailFactoryBean 我们需要执行定时执行 ScheduleTask 类中的 task 方法
- */
- jobDetail.setTargetMethod("task");
- return jobDetail;
- }
- /**
- * Details: 配置定时任务的触发器, 也就是什么时候触发执行定时任务
- */
- @Bean(name = "jobTrigger")
- public CronTriggerFactoryBean cronJobTrigger(JobDetail jobDetail) {
- CronTriggerFactoryBean tigger = new CronTriggerFactoryBean();
- tigger.setJobDetail(jobDetail);
- // 初始时的 cron 表达式, 可以改成从数据库中获取
- tigger.setCronExpression("0/2 * * * * ?");
- // trigger 的 name
- tigger.setName("tiggerName");
- return tigger;
- }
- /**
- * Details: 定义 quartz 调度工厂
- */
- @Bean(name = "scheduler")
- public SchedulerFactoryBean schedulerFactory(Trigger trigger) {
- SchedulerFactoryBean bean = new SchedulerFactoryBean();
- // 用于 quartz 集群, QuartzScheduler 启动时更新己存在的 Job
- bean.setOverwriteExistingJobs(true);
- // 延时启动, 应用启动 1 秒后
- bean.setStartupDelay(1);
- // 注册触发器
- bean.setTriggers(trigger);
- return bean;
- }
- }
新建 Task 任务
- @Service
- public class Task3 {
- @Resource(name = "jobTrigger")
- private CronTrigger cronTrigger;
- @Resource(name = "scheduler")
- private Scheduler scheduler;
- private static Log logger = LogFactory.getLog(Task3.class);
- public void task() {
- logger.info("Task3---------" + new Date());
- }
- /**
- * 设置 cron 并重启定时器
- * @param cron cron 值
- */
- public void setCron(String cron) {
- try {
- // 表达式调度构建器
- CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cron);
- // 按新的 cronExpression 表达式重新构建 trigger
- CronTrigger trigger = (CronTrigger) scheduler.getTrigger(cronTrigger.getKey());
- trigger = trigger.getTriggerBuilder().withIdentity(cronTrigger.getKey())
- .withSchedule(scheduleBuilder).build();
- // 按新的 trigger 重新设置 job 执行
- scheduler.rescheduleJob(cronTrigger.getKey(), trigger);
- } catch (SchedulerException e) {
- logger.info("cron 表达式错误");
- }
- }
- }
其中 setCron 方法可以进行重新设定任务调度时间
ThreadPoolTaskScheduler Runnable 方式
- public class Task4 implements Runnable {
- private ThreadPoolTaskScheduler threadPoolTaskScheduler;
- private static Log logger = LogFactory.getLog(Task4.class);
- @Override
- public void run() {
- logger.info("Task4================" + new Date());
- }
- /**
- * 设置 cron 并启动
- * @param cronExp cron 值
- */
- public void reStart(String cronExp) {
- if (null != this.threadPoolTaskScheduler) {
- ScheduledExecutorService scheduledExecutorService = this.threadPoolTaskScheduler.getScheduledExecutor();
- if (!scheduledExecutorService.isShutdown()) {
- scheduledExecutorService.shutdownNow();
- }
- this.threadPoolTaskScheduler.destroy();
- }
- if (null != cronExp && cronExp.trim().length()> 0) {
- this.threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
- this.threadPoolTaskScheduler.setThreadNamePrefix("task4");
- this.threadPoolTaskScheduler.initialize();
- this.threadPoolTaskScheduler.schedule(this, new CronTrigger(cronExp));
- }
- }
- }
其中 reStart 可以进行任务启动和重新设置任务调度时间, 调用方式如下所示
- /**
- * 初始化 task4
- * 这里的代码不应该写在 REST 层上, 应该写在 service 层上
- */
- @PostConstruct
- private void initTask4() {
- // 初始化 task4 任务调度器 cron, 可以从数据库中查询到 cron 值
- setTask4Cron("0/3 * * * * ?");
- }
- /**
- * 改变 task4 的 cron
- * @param cron cron 值
- * @return 成功标志
- */
- @RequestMapping(value = { "/setTask4Cron" }, method = RequestMethod.GET)
- @ResponseBody
- public String setTask4Cron(String cron) {
- if (null == task4) {
- task4 = new Task4();
- }
- task4.reStart(cron);
- return "success";
- }
initTask4 方法加了 @PostConstruct'注解, 可以在项目启动时自动根据 cron 来启动任务, setTask4Cron 方法可以重新调置任务时间
四个任务的效果如下:
来源: https://www.cnblogs.com/cnJun/p/10546745.html