Quartz
Quartz 是一个开源的 Java 任务调度框架,用于在应用程序中调度和管理任务,可以与 Spring 等框架无缝集成。
主要特性
- 调度任务:
Quartz
可以调度和执行任意的Java
任务(Job
),这些任务可以按照特定的时间表(Schedule
)运行。 - 持久化:
Quartz
支持将调度信息存储在数据库中,这使得任务的调度信息在系统重启后不会丢失。 - 分布式调度:
Quartz
可以在分布式环境中运行,支持多台机器之间的任务协调。 - 支持复杂的调度:
Quartz
支持简单和复杂的调度,包括按时间间隔、按日期、按CRON
表达式等多种方式调度任务。 - 事务支持:
Quartz
提供对事务的支持,可以在任务执行过程中使用事务管理。
核心组件
Scheduler
:调度器是Quartz
的核心组件,负责管理和调度所有的任务。Scheduler
提供了启动、停止和查询调度信息的方法。Job
:任务是由用户实现的一个接口Job
或继承的一个抽象类QuartzJobBean
,定义了具体要执行的逻辑。每个任务类都必须实现execute
方法。JobDetail
:JobDetail
是Quartz
的任务定义,它包了任务实例和任务的相关配置信息。Trigger
:触发器定义了任务的调度计划,包括任务何时执行。Quartz
提供了多种触发器,如简单触发器(SimpleTrigger
)和CRON
触发器(CronTrigger
)。JobStore
:JobStore
负责持久化调度信息。Quartz
提供了内存存储(RAMJobStore
)和数据库存储(JDBCJobStore
)等多种存储方式。
JobDetail
配置
任务详情,要做的事情。
1.MethodInvokingJobDetailFactoryBean
可以配置目标 Bean
和目标方法,缺点:不支持传参。
@Bean
MethodInvokingJobDetailFactoryBean methodInvokingJobDetailFactoryBean() {
MethodInvokingJobDetailFactoryBean bean = new MethodInvokingJobDetailFactoryBean();
// 目标对象
bean.setTargetBeanName("myJob1");
// 目标方法
bean.setTargetMethod("job1");
return bean;
}
/**
* 将Job注册到 Spring, 缺点:无法传参。
*/
@Component
public class MyJob1 {
public void job1() {
System.out.println("Executing MyJob1: " + System.currentTimeMillis());
}
}
2.JobDetailFactoryBean
任务类继承 QuartzJobBean
,支持传参,将参数封装在 JobDataMap
中进行传递。
@Bean
JobDetailFactoryBean jobDetailFactoryBean() {
JobDetailFactoryBean bean = new JobDetailFactoryBean();
bean.setJobClass(MyJob2.class);
JobDataMap map = new JobDataMap();
// 设置参数
map.put("userService", userService);
bean.setJobDataMap(map);
return bean;
}
/**
* 可通过JobDataMap传递参数
*/
@Slf4j
public class MyJob2 extends QuartzJobBean {
@Override
protected void executeInternal(JobExecutionContext jobExecutionContext)
throws JobExecutionException {
JobDataMap map = jobExecutionContext.getMergedJobDataMap();
// 通过JobDataMap获取参数
UserService userService = (UserService) map.get("userService");
User user = userService.getUserById(1L);
log.info("MyJob2: {}", user);
}
}
Trigger
配置
触发器,什么时候做。Quartz
中定义了多个触发器,如:SimpleTrigger
和 CronTrigger
。
1.SimpleTrigger
// 定义trigger
@Bean
SimpleTriggerFactoryBean simpleTriggerFactoryBean(JobDetail jobDetail) {
SimpleTriggerFactoryBean bean = new SimpleTriggerFactoryBean();
bean.setJobDetail(jobDetail);
// 时间间隔
bean.setRepeatInterval(1000);
// 重复次数,可以不设置,一直执行
// bean.setRepeatCount(5);
return bean;
}
@Bean
SchedulerFactoryBean schedulerFactoryBean(Trigger trigger) {
SchedulerFactoryBean bean = new SchedulerFactoryBean();
// 设置trigger
bean.setTriggers(trigger);
return bean;
}
2.CronTrigger
// 定义trigger
@Bean
CronTriggerFactoryBean cronTrigger(JobDetail jobDetail) {
CronTriggerFactoryBean bean = new CronTriggerFactoryBean();
// 每5秒执行一次
bean.setCronExpression("0/5 * * * * ?");
bean.setJobDetail(jobDetail);
return bean;
}
@Bean
SchedulerFactoryBean schedulerFactoryBean(Trigger trigger) {
SchedulerFactoryBean bean = new SchedulerFactoryBean();
// 设置trigger
bean.setTriggers(trigger);
return bean;
}
JobFactory
配置
Quartz
能够使用 Spring
管理的 bean
,多种方式,如:
JobDataMap
传递的参数为bean
- 配置
JobFactory
@Bean
public SpringBeanJobFactory jobFactory() {
return new SpringBeanJobFactory() {
@Override
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
Object jobInstance = super.createJobInstance(bundle);
// 注入 Spring 管理的 Bean
beanFactory.autowireBean(jobInstance);
return jobInstance;
}
};
}
SpringBoot集成 Quartz
SpringBoot
集成 Quartz
,可以实现定时任务的管理和执行。
步骤一:添加依赖
在pom.xml
文件中添加 Quartz
的依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
步骤二:创建任务类
编写一个继承 QuartzJobBean
抽象类的任务类:
普通类
public class MyJob extends QuartzJobBean {
@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
System.out.println("Executing MyJob: " + System.currentTimeMillis());
}
}
服务类
@Component
public class MyJob extends QuartzJobBean {
// 注入要使用的Spring组件
@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
System.out.println("Executing MyJob: " + System.currentTimeMillis());
}
}
步骤三:配置 Quartz
在SpringBoot
应用程序中配置 Quartz
:
@Configuration
@RequiredArgsConstructor
public class QuartzConfig {
private final AutowireCapableBeanFactory beanFactory;
/**
* 1.定义任务
*/
@Bean
public JobDetailFactoryBean jobDetail() {
JobDetailFactoryBean factoryBean = new JobDetailFactoryBean();
factoryBean.setJobClass(MyJob.class);
factoryBean.setDescription("MyJob");
factoryBean.setDurability(true);
return factoryBean;
}
/**
* 2.定义触发器
*/
@Bean
public SimpleTriggerFactoryBean trigger(JobDetail jobDetail) {
SimpleTriggerFactoryBean factoryBean = new SimpleTriggerFactoryBean();
factoryBean.setJobDetail(jobDetail);
// 时间间隔
factoryBean.setRepeatInterval(5000);
// 重复次数,可以不设置,一直执行
// factoryBean.setRepeatCount(5);
return factoryBean;
}
/**
* 3.定义Spring任务工厂: Quartz能够使用 Spring 管理的 bean
*/
@Bean
public SpringBeanJobFactory jobFactory() {
return new SpringBeanJobFactory() {
@Override
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
Object jobInstance = super.createJobInstance(bundle);
// 注入 Spring 管理的 Bean
beanFactory.autowireBean(jobInstance);
return jobInstance;
}
};
}
/**
* 4.设置调度器:jobDetail、trigger、jobFactory
*/
@Bean
public SchedulerFactoryBean scheduler(JobDetail jobDetail, Trigger trigger, JobFactory jobFactory) {
SchedulerFactoryBean factoryBean = new SchedulerFactoryBean();
factoryBean.setJobFactory(jobFactory);
factoryBean.setJobDetails(jobDetail);
factoryBean.setTriggers(trigger);
return factoryBean;
}
}
启动应用程序,检查控制台输出,可以看到每隔5秒打印一次 Executing MyJob
的信息。
Executing MyJob: 1721983542230
Executing MyJob: 1721983547233
Executing MyJob: 1721983552235
Executing MyJob: 1721983557237
Executing MyJob: 1721983562235