Quartz 定时任务整合SpringBootDome
Quartz 定时任务整合SpringBootDome
Quartz 的四核心对象
-
Job
Job 汉语工作的意思,也不难看出这是一个放具体要执行的业务代码;
-
JobDetail
JobDetail 这个是任务详情,把那个具体的任务关联起来(关联具体的Job)
-
Trigger
Trigger 这个是触发器,是要触发要执行的任务
-
Scheduler
Scheduler 调度器 是要把所有的任务详情和触发器都注册尽量,进行管理,(Scheduler 是单例模式)
进入maven 坐标
quartz需要spring-context的支持,所以引入 spring-context-support
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.3.2</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>5.3.9</version>
</dependency>
代码实现
- 配置调度器 Schedule(此处借鉴renren-fast 的定时任务配置)
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import javax.sql.DataSource;
import java.util.Properties;
/**
* @Description Description
* @Author 张凯强
* @Date Created in 2021/8/25
* @E-mail 248048521@qq.com
*/
@Configuration
public class ScheduleConfig {
@Bean
public SchedulerFactoryBean schedulerFactoryBean(DataSource dataSource) {
SchedulerFactoryBean factory = new SchedulerFactoryBean();
factory.setDataSource(dataSource);
//quartz参数
Properties prop = new Properties();
prop.put("org.quartz.scheduler.instanceName", "RenrenScheduler");
prop.put("org.quartz.scheduler.instanceId", "AUTO");
//线程池配置
prop.put("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool");
prop.put("org.quartz.threadPool.threadCount", "20");
prop.put("org.quartz.threadPool.threadPriority", "5");
//JobStore配置
prop.put("org.quartz.jobStore.class", "org.quartz.impl.jdbcjobstore.JobStoreTX");
//集群配置
prop.put("org.quartz.jobStore.isClustered", "true");
prop.put("org.quartz.jobStore.clusterCheckinInterval", "15000");
prop.put("org.quartz.jobStore.maxMisfiresToHandleAtATime", "1");
prop.put("org.quartz.jobStore.misfireThreshold", "12000");
prop.put("org.quartz.jobStore.tablePrefix", "QRTZ_");
prop.put("org.quartz.jobStore.selectWithLockSQL", "SELECT * FROM {0}LOCKS UPDLOCK WHERE LOCK_NAME = ?");
//PostgreSQL数据库,需要打开此注释
//prop.put("org.quartz.jobStore.driverDelegateClass", "org.quartz.impl.jdbcjobstore.PostgreSQLDelegate");
factory.setQuartzProperties(prop);
factory.setSchedulerName("RenrenScheduler");
//延时启动
factory.setStartupDelay(30);
factory.setApplicationContextSchedulerContextKey("applicationContextKey");
//可选,QuartzScheduler 启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了
factory.setOverwriteExistingJobs(true);
//设置自动启动,默认为true
factory.setAutoStartup(true);
// factory.setTaskExecutor();
return factory;
}
}
- 创建一个任务
import lombok.SneakyThrows;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.PersistJobDataAfterExecution;
import org.springframework.scheduling.quartz.QuartzJobBean;
/**
* @Description 创建一个任务
* @Author 张凯强
* @Date Created in 2021/8/25
* @E-mail 248048521@qq.com
*/
//@PersistJobDataAfterExecution // 单例实例化
//@DisallowConcurrentExecution // 禁止并发执行
public class QuartzJob extends QuartzJobBean {
@SneakyThrows
@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
// context.getScheduler() 调度器
Scheduler scheduler = context.getScheduler();
// context.getTrigger() 触发器
Trigger trigger = context.getTrigger();
System.out.println(new Date());
// 可以在创建任务详情时传值进来,这里可以获取
System.out.println(trigger.getJobDataMap().get("zkq"));
// context.getJobDetail() 任务
JobDetail jobDetail = context.getJobDetail();
System.out.println(jobDetail.getJobDataMap().get("zkq"));
}
- 服务层和服务实现层
/**
* @Description Description
* @Author 张凯强
* @Date Created in 2021/8/25
* @E-mail 248048521@qq.com
*/
public interface ScheduleJobService {
}
/**
* @Description Description
* @Author 张凯强
* @Date Created in 2021/8/25
* @E-mail 248048521@qq.com
*/
@Service
public class ScheduleJobServiceImpl implements ScheduleJobService {
//注入调度器
@Autowired
Scheduler scheduler;
/**
* 项目启动时,初始化定时器
*/
@PostConstruct // 在对象初始化时执行
public void init(){
System.out.println("开始...");
// 创建一个 触发器key
TriggerKey triggerKey = new TriggerKey("trigger", "group");
try {
// 获取这个触发器
Trigger trigger = scheduler.getTrigger(triggerKey);
if (trigger == null){
// 触发器为空时构建一个触发器 0/10 * * * * ? 每10秒触发一次 规则请自行百度cron表达式
trigger = TriggerBuilder.newTrigger().withIdentity(triggerKey)
.withSchedule(CronScheduleBuilder.cronSchedule("0/10 * * * * ?").withMisfireHandlingInstructionDoNothing()).build();
rigger.getJobDataMap().put("zkq","aaa");
// 构建一个任务详情, 把任务放进来,这个对象类型为class,这里是 QuartzJob.class
JobDetail jobDetail = JobBuilder.newJob(QuartzJob.class).withIdentity("job", "group").build();
// 把之任务和触发器注册进调度器中
jobDetail.getJobDataMap().put("zkq","每天努力一点点!");
scheduler.scheduleJob(jobDetail, trigger);
// scheduler.triggerJob();
// 运行这个调度器
// scheduler.start();
}
} catch (SchedulerException e) {
e.printStackTrace();
}
}
}
成功结果
到此结束!有错误欢迎提出,大神勿喷!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了