市面上定时任务实现的方式千人千种,百度上也是各种款式,开发这么久总得总结点相对来说好点的东西。
给大家介绍一下我目前在用的Quartz,简单易懂,好上手;没有废话,直接开始cv吧。注意:文末有彩蛋
1.导入maven依赖,这些依赖都需要用到,如果有重复去掉即可,quartz与springboot版本一样,我的是 2.1.5
<dependency>
<groupId>net.sourceforge.nekohtml</groupId>
<artifactId>nekohtml</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.2</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
2.添加配置类 SchedulerConfig
package cn.cnic.zhongtai.dataimport.config;
import org.quartz.Scheduler;
import org.quartz.ee.servlet.QuartzInitializerListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.PropertiesFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import java.io.IOException;
import java.util.Properties;
/**
* quartz配置
* 创建者 wdd
* 创建时间 2018年4月3日
*/
@Configuration
public class SchedulerConfig {
@Autowired
private SpringJobFactory springJobFactory;
@Bean(name="SchedulerFactory")
public SchedulerFactoryBean schedulerFactoryBean() throws IOException {
SchedulerFactoryBean factory = new SchedulerFactoryBean();
factory.setAutoStartup(true);
factory.setStartupDelay(5);//延时5秒启动
factory.setQuartzProperties(quartzProperties());
factory.setJobFactory(springJobFactory);
return factory;
}
@Bean
public Properties quartzProperties() throws IOException {
PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
propertiesFactoryBean.setLocation(new ClassPathResource("/quartz.properties"));
propertiesFactoryBean.afterPropertiesSet();
return propertiesFactoryBean.getObject();
}
/*
* quartz初始化监听器
*/
/* @Bean
public QuartzInitializerListener executorListener() {
return new QuartzInitializerListener();
}*/
/*
* 通过SchedulerFactoryBean获取Scheduler的实例
*/
@Bean(name="Scheduler")
public Scheduler scheduler() throws IOException {
return schedulerFactoryBean().getScheduler();
}
}
3.添加一个任务试试,5秒执行一次
LOGGER.info("初始化测试任务");
QuartzEntity quartz = new QuartzEntity();
quartz.setJobName("test01");
quartz.setJobGroup("test");
quartz.setDescription("测试任务");
quartz.setJobClassName("com.itstyle.quartz.job.ChickenJob");
quartz.setCronExpression("*/5 * * * * ?");
quartz.setJobMethodName("test1");
Class cls = Class.forName(quartz.getJobClassName()) ;
cls.newInstance();
//构建job信息
JobDetail job = JobBuilder.newJob(cls).withIdentity(quartz.getJobName(),
quartz.getJobGroup())
.withDescription(quartz.getDescription()).build();
job.getJobDataMap().put("jobMethodName", "test1");
// 触发时间点
CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(quartz.getCronExpression());
Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger"+quartz.getJobName(), quartz.getJobGroup())
.startNow().withSchedule(cronScheduleBuilder).build();
//交由Scheduler安排触发
scheduler.scheduleJob(job, trigger);
4.创建ChickenJob ,
package com.itstyle.quartz.job;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.quartz.*;
/**
* 实现序列化接口、防止重启应用出现quartz Couldn't retrieve job because a required class was not found 的问题
* Job 的实例要到该执行它们的时候才会实例化出来。每次 Job 被执行,一个新的 Job 实例会被创建。
* 其中暗含的意思就是你的 Job 不必担心线程安全性,因为同一时刻仅有一个线程去执行给定 Job 类的实例,甚至是并发执行同一 Job 也是如此。
* @DisallowConcurrentExecution 保证上一个任务执行完后,再去执行下一个任务,这里的任务是同一个任务
*/
@DisallowConcurrentExecution
public class ChickenJob implements Job,Serializable {
private static final long serialVersionUID = 1L;
@Override
public void execute(JobExecutionContext context){
JobDetail jobDetail = context.getJobDetail();
JobDataMap dataMap = jobDetail.getJobDataMap();
/**
* 获取任务中保存的方法名字,动态调用方法
*/
String methodName = dataMap.getString("jobMethodName");
try {
ChickenJob job = new ChickenJob();
Method method = job.getClass().getMethod(methodName);
method.invoke(job);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
public void test1(){
System.out.println("测试方法1王栋栋啊");
}
public void test2(){
System.out.println("测试方法2");
}
}
主要代码就这些,这只是一个流程,说好的彩蛋也来了。
具体就看彩蛋的表现吧,如果有问题欢迎留言讨论。。。qq:983469079