參考地址: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()); } }