参考地址:https://mp.weixin.qq.com/s/3_8yfRMzpJ5ZrRTiOOeP5w
一、maven依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
补充:此处采用的内嵌数据库H2+spring data jpa
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
二、配置信息
1、application.yml
server: port: 8081 spring: datasource:
#数据库存储路径(./database/job表示和项目代码同级) url: jdbc:h2:./database/job driver-class-name: org.h2.Driver username: yzh password: 123456 jpa: database: h2 hibernate: ddl-auto: update show-sql: true h2: console: path: /h2-console enabled: true
2、配置类(QuartzConfig)

@Configuration public class QuartzConfig { @Autowired private JobFactory jobFactory; @Bean public SchedulerFactoryBean schedulerFactoryBean() throws IOException { SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean(); schedulerFactoryBean.setOverwriteExistingJobs(true); schedulerFactoryBean.setQuartzProperties(quartzProperties()); schedulerFactoryBean.setJobFactory(jobFactory); return schedulerFactoryBean; } /** * 指定quartz.properties,可在配置文件中配置相关属性 * @return * @throws IOException */ public Properties quartzProperties() throws IOException { PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean(); propertiesFactoryBean.setLocation(new ClassPathResource("/config/quartz.properties")); propertiesFactoryBean.afterPropertiesSet(); return propertiesFactoryBean.getObject(); } /** * 创建schedule * @return * @throws IOException */ @Bean(name = "scheduler") public Scheduler scheduler() throws IOException { return schedulerFactoryBean().getScheduler(); } }
3、实体类(SysTask)

@Entity public class SysTask implements Serializable { private static final long serialVersionUID = -560378047531235168L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; /** * 任务名 */ private String jobName; /** * 任务描述 */ private String description; /** * cron表达式 */ private String cronExpression; /** * 任务执行时调用哪个类的方法 包名+类名 */ private String beanClass; /** * 任务状态 */ private String jobStatus; /** * 任务分组 */ private String jobGroup; /** * 创建者 */ private String createUser; /** * 创建时间 */ private Date createTime; /** * 更新者 */ private String updateUser; /** * 更新时间 */ private Date update_time;
对应的dao(ISysTaskDao)
@Component public interface ISysTaskDao extends JpaRepository<SysTask,Long> { }
4、添加监听器(ScheduleJobInitListener)
项目启动时,初始化任务
@Component @Order(1) public class ScheduleJobInitListener implements CommandLineRunner { @Autowired private ISysTakService takService; @Override public void run(String... args) throws Exception { takService.initSchedule(); } }
5、读取数据库,加载scheduler调度器
(1)、获取数据库中的任务
@Service public class SysTakServiceImpl implements ISysTakService { @Autowired private ISysTaskDao sysTaskDao; @Autowired private QuartzManager quartzManager; @Transactional(readOnly = true,propagation = Propagation.NOT_SUPPORTED) @Override public void initSchedule() throws Exception { //获取任务信息
List<SysTask> all = sysTaskDao.findAll(); /** * 正在运行的 */
for (SysTask sysTask : all) { if (JobStatusEnum.RUNNING.getStatus().equals(sysTask.getJobStatus())){ quartzManager.addJob(sysTask); } } } }
(2)、添加任务到Quartz调度器
@Component public class QuartzManager { private static final Logger LOGGER = LoggerFactory.getLogger(QuartzManager.class); @Autowired private Scheduler scheduler; /** * 添加并启动任务 * @param task */ @SuppressWarnings("unchecked") public void addJob(SysTask task) throws Exception { //创建jobDetail实例,绑定job实现类
Class<? extends Job> jobClass = (Class<? extends Job>) (Class.forName(task.getBeanClass()).newInstance() .getClass()); JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(task.getJobName(), task.getJobGroup()).build(); //定义调度触发规则
Trigger trigger = TriggerBuilder.newTrigger().withIdentity(task.getJobName(), task.getJobGroup())// 触发器key
.startAt(DateBuilder.futureDate(1, DateBuilder.IntervalUnit.SECOND)) .withSchedule(CronScheduleBuilder.cronSchedule(task.getCronExpression())).startNow().build(); //把作业和触发器注册到任务调度中
scheduler.scheduleJob(jobDetail,trigger); //启动
if (!scheduler.isShutdown()){ scheduler.start(); } } }
6、实例化job类,注入要运行的service
(1)、工厂类(JobFactory)
@Component public class JobFactory extends AdaptableJobFactory { @Autowired private AutowireCapableBeanFactory capableBeanFactory; @Override protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception { //调用父类的方法
Object jobInstance = super.createJobInstance(bundle); //进行注入
capableBeanFactory.autowireBean(jobInstance); return jobInstance; } }
(2)、具体任务类
@DisallowConcurrentExecution //不允许多线程运行 @Component public class HelloWorldJob implements Job { private static final Logger LOGGER = LoggerFactory.getLogger(HelloWorldJob.class); @Override public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { JobKey key = jobExecutionContext.getJobDetail().getKey(); LOGGER.info("任务【{}】-【{}】执行开始了--:{}",key.getName(),key.getGroup(),new Date()); } }