什么是Quzrtz?
Quartz是一个开源任务调度框架,可以根据用户设定的时间规则来执行作业。简单来说,用户可以提前设定时间,规定好该时间所需要做的任务,当到达设定时间时,该任务便会按照原先定好的流程运行。
运用场景
1.定时轮询数据库同步 2.定时邮件通知 3.定时在线考试 4.等等
Quartz核心组件
任务:JobDetail
Job(任务):是一个接口,可以通过实现该接口来定义需要执行的任务。 JobDetail是用来描述Job实现类以及相关静态信息,比如任务在scheduler中的任务名、组名等信息。
触发器:Trigger
描述触发Job执行的时间触发规则
调度器:Scheduler
用来连接Trigger和JobDetail,可以将Trigger绑定到某一JobDetail上,这样当Trigger被触发时,对应的Job就会执行
使用Quzrtz
导入依赖
使用的版本是2.3.5.RELEASE,可相应进行调整
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
<version>2.3.5.RELEASE</version>
</dependency>
创建 QuartzManager类
该类的作用是提供定时任务的创建、修改、移除等操作
@Component
public class QuartzManager {
private static final SchedulerFactory schedulerFactory = new StdSchedulerFactory();
@SuppressWarnings({ "unchecked", "rawtypes" })
public void addJob(String jobName, String jobGroupName,
String triggerName, String triggerGroupName, Class jobClass, String cron) {
try {
Scheduler sched = schedulerFactory.getScheduler();
JobDetail jobDetail= JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName).build();
TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();
triggerBuilder.withIdentity(triggerName, triggerGroupName);
triggerBuilder.startNow();
triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron));
CronTrigger trigger = (CronTrigger) triggerBuilder.build();
sched.scheduleJob(jobDetail, trigger);
if (!sched.isShutdown()) {
sched.start();
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public void modifyJobTime(String jobName,
String jobGroupName, String triggerName, String triggerGroupName, String cron) {
try {
Scheduler sched = schedulerFactory.getScheduler();
TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName);
CronTrigger trigger = (CronTrigger) sched.getTrigger(triggerKey);
if (trigger == null) {
return;
}
String oldTime = trigger.getCronExpression();
if (!oldTime.equalsIgnoreCase(cron)) {
TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();
triggerBuilder.withIdentity(triggerName, triggerGroupName);
triggerBuilder.startNow();
triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron));
trigger = (CronTrigger) triggerBuilder.build();
sched.rescheduleJob(triggerKey, trigger);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public void removeJob(String jobName, String jobGroupName,
String triggerName, String triggerGroupName) {
try {
Scheduler sched = schedulerFactory.getScheduler();
TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName);
sched.pauseTrigger(triggerKey);
sched.unscheduleJob(triggerKey);
sched.deleteJob(JobKey.jobKey(jobName, jobGroupName));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public void startJobs() {
try {
Scheduler sched = schedulerFactory.getScheduler();
sched.start();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public void shutdownJobs() {
try {
Scheduler sched = schedulerFactory.getScheduler();
if (!sched.isShutdown()) {
sched.shutdown();
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
创建QuartzCronDateUtils类
该类作用为将Date类型的数据转化为Cron类型的表达式。 由于Quartz定时任务使用的日期形式为corn,所以需要增加一个格式转换类。
public class QuartzCronDateUtils {
public static String formatDateByPattern(Date date, String dateFormat) {
SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
String formatTimeStr = null;
if (date != null) {
formatTimeStr = sdf.format(date);
}
return formatTimeStr;
}
public static String getCron(java.util.Date date) {
String dateFormat = "ss mm HH dd MM ? yyyy";
return formatDateByPattern(date, dateFormat);
}
}
测试Quartz
创建SpringApplicationUtils类
该类的可以获取类对象的实例。 由于我们后面写任务逻辑(实现接口 Job类)时可能会需要进行一些方法的注入,例如在任务逻辑中需要使用我们自己写的一些service类,因为Quartz在实例化对象的时候没有经过Spring的处理,那么就意味着在Spring的IOC容器当中没有对应的对象,导致我们自己的一些类无法成功注入。因此需要使用SpringApplicationUtils中的getBean方法手动获取实例对象。
@Component
public class SpringApplicationUtils implements ApplicationContextAware {
private static ApplicationContext applicationContext = null;
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
if (SpringApplicationUtils.applicationContext == null) {
SpringApplicationUtils.applicationContext = applicationContext;
}
}
public static Object getBean(String name) {
return getApplicationContext().getBean(name);
}
public static <T> T getBean(Class<T> clazz) {
return getApplicationContext().getBean(clazz);
}
public static <T> T getBean(String name, Class<T> clazz) {
return getApplicationContext().getBean(name, clazz);
}
public static <T> Map<String, T> getBeansOfType(Class<T> clazz) {
Map<String, T> instances = getApplicationContext().getBeansOfType(clazz);
return instances;
}
}
创建TestService类
@Service
@Slf4j
public class TestService {
public void Test(){
log.info("Test.....");
}
}
创建TestQuartz类
实现Job接口中的execute方法,写定时任务逻辑
public class TestQuartz implements Job {
TestService testService = SpringApplicationUtils.getBean(TestService.class);
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
testService.Test();
}
}
创建QuartzJobListener类(不是必要的,可自行增减)
该类作用为创建定时任务
@Service
public class QuartzJobListener {
@Autowired
QuartzManager quartzManager;
public void contextInitialized() {
List<Map<String,Object>> listMap=new ArrayList<>();
String corn = QuartzCronDateUtils.getCron(new Date(122,1,8,23,0));
for(int i = 1; i <= 3; i++){
Map<String, Object> map = new HashMap<String, Object>();
map.put("jobName","jobName" + i);
map.put("jobGroupName","jobGroupName" + i);
map.put("triggerName","triggerName" + i);
map.put("triggerGroupName","triggerGroupName" + i);
map.put("jobTime",corn);
listMap.add(map);
}
for (Map<String, Object> oneMap : listMap) {
try {
quartzManager.addJob(oneMap.get("jobName").toString(),oneMap.get("jobGroupName").toString(), oneMap.get("triggerName").toString(), oneMap.get("triggerGroupName").toString(), TestQuartz.class, oneMap.get("jobTime").toString());
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
创建ApplicationQuartzRunner类
该类作用为在项目启动时,开启定时任务(实际就是QuartzJobListener类中的创建定时任务)
@Component
public class ApplicationQuartzRunner implements ApplicationRunner {
@Autowired
QuartzJobListener quartzJobListener;
@Override
public void run(ApplicationArguments args) throws Exception {
quartzJobListener.contextInitialized();
System.out.println("QuartzJobListener 启动了");
}
}
结果
最后测试结果,三个定时任务都在2022年2月8号23整点触发了
|