springboot的schedule和quartz两种定时任务的设置

  • Post author:
  • Post category:其他


组件名称 cron 持久化 开发难以程度
schedule 支持 不支持 非常简单
quartz 支持 支持 复杂

schedule配置只需注解就行

@Configuration
@Slf4j
publicclass ScheduleConfig implements SchedulingConfigurer {
    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.setScheduler(taskExecutor());    
    }
    @Bean
    public Executor taskExecutor(){
        return Executors.newScheduledThreadPool(10);
    }
}
@Component
@Slf4j
public class SbScheduleTask1 {
    @Async
    @Scheduled(cron = "*/2 * * * * ?")
    public void task1() throws InterruptedException {
        log.error("我是task1111,我需要执行 10s 钟的时间,我的线程的 id == > {},时间 == >{}", Thread.currentThread().getId(), new Date());
        Thread.sleep(10000);
        log.error("task1111 ending ,我的线程的 id == > {} , 时间 == > {}", Thread.currentThread().getId(), new Date());
    }
    @Async
    @Scheduled(cron = "*/4 * * * * ?")
    public void task2() throws InterruptedException {
        log.error("我是task2222,我需要执行 2s 钟的时间,我的线程的 id == > {},时间 == >{}", Thread.currentThread().getId(), new Date());
        Thread.sleep(2000);
        log.error("task2222 ending ,我的线程的 id == > {} , 时间 == > {}", Thread.currentThread().getId(), new Date());
    }
}

而quartz



先springmvc配法

<dependency>
      <groupId>org.quartz-scheduler</groupId>
      <artifactId>quartz</artifactId>
      <version>2.2.1</version>
    </dependency>

配置文件


org.quartz.scheduler.instanceName = MyScheduler
org.quartz.threadPool.threadCount = 3
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.tablePrefix = QRTZ_
org.quartz.jobStore.dataSource = qzDS

#JDBC驱动
org.quartz.dataSource.qzDS.driver:com.mysql.jdbc.Driver
org.quartz.dataSource.qzDS.URL:jdbc:mysql://localhost:3306/lawyer
org.quartz.dataSource.qzDS.user:root
org.quartz.dataSource.qzDS.password:123456
org.quartz.dataSource.qzDS.maxConnection:10

org.quartz.scheduler.skipUpdateCheck =true  

spring.xml

<?xml version="1.0" encoding="UTF-8"?>  
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	   xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="
	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
	http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
	">

	<!-- 使用Annotation自动注册Bean,解决事物失效问题:在主容器中不扫描@Controller注解,在SpringMvc中只扫描@Controller注解。  -->
	<context:component-scan base-package="cn.huashantech.lawyer"><!-- base-package 如果多个,用“,”分隔 -->
		<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
	</context:component-scan>

	<!-- 引入属性文件 -->
	<bean id="propertyConfigurer"
		class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
		<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
		<property name="ignoreResourceNotFound" value="true" />
		<property name="locations">
			<list>
				<value>classpath:jdbc.properties</value>
			</list>
		</property>
	</bean>

	<import resource="spring-web.xml"/>

	<!-- 使用MethodInvokingJobDetailFactoryBean,任务类可以不实现Job接口,通过targetMethod指定调用方法-->
	<bean id="taskJob" class="cn.huashantech.lawyer.service.DataConversionTask"/>

	<bean id="jobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
		<!--false表示等上一个任务执行完后再开启新的任务-->
		<property name="concurrent" value="false"/>
		<property name="targetObject" ref="taskJob"/>
		<property name="targetMethod" value="run"/>
	</bean>

	<!--  调度触发器 -->
	<bean id="myTrigger"
		  class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
		<property name="jobDetail" ref="jobDetail"/>
		<property name="cronExpression" value="0/5 * * * * ?"/>
	</bean>


	<!-- 调度工厂 -->
	<bean  id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">

	</bean>
</beans>

实体类

package cn.huashantech.lawyer.service.DynamicTask;

import java.io.Serializable;

/**计划任务信息
 * @author lihang
 * @create 2017-11-01 下午11:17
 */
public class ScheduleJob implements Serializable {
    /** 任务id */
    private String jobId;
    /** 任务名称 */
    private String jobName;
    /** 任务分组 */
    private String jobGroup;
    /** 任务状态 0禁用 1启用 2删除*/
    private String jobStatus;
    /** 任务运行时间表达式 */
    private String cronExpression;
    /** 任务描述 */
    private String desc;

    public String getJobId() {
        return jobId;
    }

    public void setJobId(String jobId) {
        this.jobId = jobId;
    }

    public String getJobName() {
        return jobName;
    }

    public void setJobName(String jobName) {
        this.jobName = jobName;
    }

    public String getJobGroup() {
        return jobGroup;
    }

    public void setJobGroup(String jobGroup) {
        this.jobGroup = jobGroup;
    }

    public String getJobStatus() {
        return jobStatus;
    }

    public void setJobStatus(String jobStatus) {
        this.jobStatus = jobStatus;
    }

    public String getCronExpression() {
        return cronExpression;
    }

    public void setCronExpression(String cronExpression) {
        this.cronExpression = cronExpression;
    }

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }
}

计划任务map

package cn.huashantech.lawyer.service.DynamicTask;

import cn.huashantech.lawyer.service.DynamicTask.ScheduleJob;

import java.util.*;

/**
 * @author lihang
 * @create 2017-11-01 下午11:17
 */
public class DataWorkContext {
    /** 计划任务map */
    private static Map<String, ScheduleJob> jobMap = new HashMap<String, ScheduleJob>();

    static {
        for (int i = 0; i < 2; i++) {
            ScheduleJob job = new ScheduleJob();
            job.setJobId("10001" + i);
            job.setJobName("data_import" + i);
            job.setJobGroup("dataWork");
            job.setJobStatus("1");
            job.setCronExpression("0/5 * * * * ?");
            job.setDesc("数据导入任务");
            addJob(job);
        }
    }

    /**
     * 添加任务
     * @param scheduleJob
     */
    public static void addJob(ScheduleJob scheduleJob) {
        jobMap.put(scheduleJob.getJobGroup() + "_" + scheduleJob.getJobName(), scheduleJob);
    }

    public static List<ScheduleJob> getAllJob(){
        Iterator<Map.Entry<String, ScheduleJob>> entries = jobMap.entrySet().iterator();
        List<ScheduleJob> list = new ArrayList<>();
        while (entries.hasNext()) {
            Map.Entry<String, ScheduleJob> entry = entries.next();
            list.add(entry.getValue());
        }
        return list;
    }



}

定时任务运行工厂类

package cn.huashantech.lawyer.service.DynamicTask;

import cn.huashantech.lawyer.service.DynamicTask.ScheduleJob;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

/**定时任务运行工厂类
 * @author lihang
 * @create 2017-11-01 下午11:16
 */
public class QuartzJobFactory implements Job {
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        ScheduleJob scheduleJob = (ScheduleJob)context.getMergedJobDataMap().get("scheduleJob");
        System.out.println("任务名称 = [" + scheduleJob.getJobName() + "]");
    }
}
package cn.huashantech.lawyer.service.DynamicTask;

import org.quartz.*;
import org.quartz.impl.matchers.GroupMatcher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * @author lihang
 * @create 2017-11-01 下午11:21
 */
@Component
public class Main {

    @Autowired
    private Scheduler scheduler;

    /**
     * 获取正在执行的任务
     *
     * @return
     * @throws SchedulerException
     */
    public List<ScheduleJob> getScheduleJobs() throws SchedulerException {
        List<JobExecutionContext> executingJobs = scheduler.getCurrentlyExecutingJobs();
        System.out.println(executingJobs.size());
        List<ScheduleJob> jobList = new ArrayList<>(executingJobs.size());
        for (JobExecutionContext executingJob : executingJobs) {
            ScheduleJob job = new ScheduleJob();
            JobDetail jobDetail = executingJob.getJobDetail();
            JobKey jobKey = jobDetail.getKey();
            Trigger trigger = executingJob.getTrigger();
            job.setJobName(jobKey.getName());
            job.setJobGroup(jobKey.getGroup());
            System.out.println(jobKey.getGroup());
            job.setDesc("触发器:" + trigger.getKey());
            Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
            job.setJobStatus(triggerState.name());
            if (trigger instanceof CronTrigger) {
                CronTrigger cronTrigger = (CronTrigger) trigger;
                String cronExpression = cronTrigger.getCronExpression();
                job.setCronExpression(cronExpression);
            }
            jobList.add(job);
        }
        return jobList;
    }

    /**
     * 获取已经部署的任务
     *
     * @return
     * @throws SchedulerException
     */
    public List<ScheduleJob> getRunScheduleJobs() throws SchedulerException {
        GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();
        Set<JobKey> jobKeys = scheduler.getJobKeys(matcher);
        List<ScheduleJob> jobList = new ArrayList<>();
        for (JobKey jobKey : jobKeys) {
            List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
            for (Trigger trigger : triggers) {
                ScheduleJob job = new ScheduleJob();
                job.setJobName(jobKey.getName());
                job.setJobGroup(jobKey.getGroup());
                job.setDesc("触发器:" + trigger.getKey());
                Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
                job.setJobStatus(triggerState.name());
                if (trigger instanceof CronTrigger) {
                    CronTrigger cronTrigger = (CronTrigger) trigger;
                    String cronExpression = cronTrigger.getCronExpression();
                    job.setCronExpression(cronExpression);
                }
                jobList.add(job);
            }
        }
        return jobList;
    }

    /**
     * 任务初始化
     */
    public void init() {
        //mock任务数据
        List<ScheduleJob> jobList = DataWorkContext.getAllJob();
        try {
            for (ScheduleJob job : jobList) {
                TriggerKey triggerKey = TriggerKey.triggerKey(job.getJobName(), job.getJobGroup());
                //获取trigger,即在spring配置文件中定义的 bean id="myTrigger"
                CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
                //不存在,创建一个
                if (null == trigger) {
                    JobDetail jobDetail = JobBuilder.newJob(QuartzJobFactory.class)
                            .withIdentity(job.getJobName(), job.getJobGroup()).build();
                    jobDetail.getJobDataMap().put("scheduleJob", job);

                    //表达式调度构建器
                    CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job
                            .getCronExpression());

                    //按新的cronExpression表达式构建一个新的trigger
                    trigger = TriggerBuilder.newTrigger().withIdentity(job.getJobName(), job.getJobGroup()).withSchedule(scheduleBuilder).build();
                    scheduler.scheduleJob(jobDetail, trigger);
                } else {
                    // Trigger已存在,那么更新相应的定时设置
                    //表达式调度构建器
                    CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job
                            .getCronExpression());
                    //按新的cronExpression表达式重新构建trigger
                    trigger = trigger.getTriggerBuilder().withIdentity(triggerKey)
                            .withSchedule(scheduleBuilder).build();

                    //按新的trigger重新设置job执行
                    scheduler.rescheduleJob(triggerKey, trigger);
                }
            }
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }

    /**
     * 暂停任务
     *
     * @throws SchedulerException
     */
    public void stop() throws SchedulerException {
        scheduler.pauseAll();
    }

    /**
     * 恢复任务
     *
     * @throws SchedulerException
     */
    public void resume() throws SchedulerException {
        scheduler.resumeAll();
    }
}



最后springboot 兼容配法

  <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-quartz</artifactId>
  </dependency>
@Configuration
public class ScheduleConfig1 {
    protected static final Level OPERATING = Level.forName("BUS", 250);
    private static final Logger log = LogManager.getLogger();
 
 
    @Bean
 
    public JobDetail task1JobDetail() {
        return JobBuilder.newJob(Task1.class)
                .withIdentity("task1")
                .storeDurably(true)
                .build();
    }
 
    @Bean
    public JobDetail task2JobDetail() {
        return JobBuilder.newJob(Task2.class)
                .withIdentity("task2")
                .storeDurably(true)
                .build();
    }
 
    @Bean
    public Trigger task1Trigger() {
        CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule("*/4 * * * * ?");
        return TriggerBuilder.newTrigger()
                .forJob(task1JobDetail())
                .withIdentity("task1")
                .withSchedule(scheduleBuilder)
                .build();
    }
 
    @Bean
    public Trigger task2Trigger() {
        CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule("*/4 * * * * ?");
        return TriggerBuilder.newTrigger()
                .forJob(task2JobDetail())
                .withIdentity("task2")
                .withSchedule(scheduleBuilder)
                .build();
    }
}
@Slf4j
@Component
@DisallowConcurrentExecution
public class Task1 extends QuartzJobBean {
    @Override
    protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        log.error("我是task1111 ,我将执行10s钟, 线程名字 == > {} , 现在时间为 == > {}", Thread.currentThread().getId(),new Date());
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        log.error("我是task1111,我已经执行完成了,线程名字 == > {} , 现在时间为 == > {}",Thread.currentThread().getId(),new Date());
    }
}
@Component
@DisallowConcurrentExecution
public class Task2 extends QuartzJobBean {
 
    @Override
    protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        log.error("我是task2222 ,我将执行2s钟, 线程名字 == > {} , 现在时间为 == > {}", Thread.currentThread().getId(),new Date());
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getId());
        log.error("我是task2222,我已经执行完成了,线程名字 == > {} , 现在时间为 == > {}",Thread.currentThread().getId(),new Date());
    }
}



版权声明:本文为weixin_43343423原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。