最近有个小项目要做,spring mvc下的task设置一直不太灵活,因此在Spring Boot上想做到灵活的管理定时任务。需求就是,当项目启动的时候,如果有定时任务则加载进来,生成scheduler,通过后台表配置可以随时更新定时任务状态(启动、更改、删除)。
添加依赖
<!-- spring's support for quartz --> |
一个是Spring框架的支持,一个是Quartz的依赖,有的博客会加上quartz-jobs,在当前示例中没有用到,这里不做添加。
调整配置
- application.properties增加参数
#quartz enabled 设置在当前项目是否运行quartz定时任务 |
- 增加quartz配置文件quartz.properties
# thread-pool |
这些参数可以不设置,有一些默认值,threadCount的默认值是10,spring mvc下定时任务的默认值是1,所以如果某个定时任务卡住了,肯会影响其后的多个定时任务的执行。
任务表配置
- Entity
实体类,这里是JobConfig,这里没有做过多的设计,只是实现了cron类型的定时任务及任务状态,fullEntity是执行任务的类全名,如我们用的com.example.demo.jobs.MyJob
import lombok.AllArgsConstructor; |
代码没有set/get是因为使用了lombok,@Data注解实现set/get/toString等工作
- Repository
这里主要是定义了一个根据定时任务状态获取对应的定时任务的方法,JobConfigRepository
import com.example.demo.dto.JobConfig; |
- Service
调用Repository的方法,提供查询,JobConfigService
import com.example.demo.dto.JobConfig; |
添加自动注入支持
源于https://gist.github.com/jelies/5085593的解决方案,解决的问题就是在org.quartz.Job的子类里无法直接使用Service等依赖,具体如下:
import org.quartz.spi.TriggerFiredBundle; |
Scheduler工具类
实现Scheduler的增删改功能以及JobDetail、CronTrigger的创建,需要注意,这里的数据都是源于JobConfig这个表,name是FullEntity+Id拼接而成的。具体看代码可知:
import com.example.demo.config.AutoWiringSpringBeanJobFactory; |
Scheduler初始化配置
通过Spring Boot的@Configuration及@ConditionalOnExpression(“‘${quartz.enabled}’==’true’”)实现初始化时是否加载项目的定时任务——SchedulerConfig,这里的参数quartz.enabled的值即是我们上面在配置文件里配置的。代码如下:
package com.example.demo.config; |
Job实现
这里定义了一个简单的Job继承org.quartz.Job,主要是查询当前的定时任务表配置数据,MyJob,具体代码如下:
package com.example.demo.jobs; |
数据库表job_config
- 表创建
CREATE TABLE `job_config` ( |
- 表数据
/*Data for the table `job_config` */ |
运行结果
JobConfig(id=1, name=My test, fullEntity=com.example.demo.jobs.MyJob, groupName=test, cronTime=0/8 * * * * ?, status=1, createAt=2017-08-25 21:03:35.0, updateAt=null) |
到这里,Spring Boot与quartz的整合已经完成了,可以通过配置表job_config以及配置quartz.enabled参数来灵活使用定时任务了!
后续还会继续实践、丰富这个示例,如果上文有什么问题,欢迎留言指正,谢谢!
源码:https://github.com/icnws/spring-data-jpa-demo
定时任务的路还有很长,想更灵活?可能需要elastic-job等框架吧!欢迎留言交流!
http://www.icnws.com/2017/145-spring-boot-quartz-editable/