• SpringBoot2 task scheduler 定时任务调度器四种方式


    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方法可以重新调置任务时间

    四个任务的效果如下:

  • 相关阅读:
    React项目升级遇到的问题复盘(2019-09-02)
    前端项目升级到React-router5中遇到的问题解决方案以及思路
    三行Jquery代码实现简单的选项卡
    开放-封闭原则
    单一职责原则
    简单工厂模式(c++实现)
    博客园使用MarkDown格式记录博客
    Qml 的Image对应的source不变,但是图片内容改变却不会刷新的解决方案
    Qt中第一请求web api连接返回缓慢问题
    Qt的pro文件工程配置
  • 原文地址:https://www.cnblogs.com/cnJun/p/10546745.html
Copyright © 2020-2023  润新知