组件名称 | 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 版权协议,转载请附上原文出处链接和本声明。