文章首发于博主的公众号:Java4y
2021一起好好加油! (ง •_•)ง
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-quartzartifactId>
dependency>
job
并继承 QuartzJobBean
package com.java4ye.demo.job;
import lombok.extern.slf4j.Slf4j;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobKey;
import org.springframework.scheduling.quartz.QuartzJobBean;
/**
* @author Java4ye
* @date 2021/1/9 10:50
* @微信公众号: Java4ye
* @GitHub https://github.com/RyzeYang
* @博客 https://blog.csdn.net/weixin_40251892
*/
@Slf4j
public class HelloWorldJob extends QuartzJobBean {
@Override
protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
JobKey key = jobExecutionContext.getJobDetail().getKey();
log.info("[JobKey] name:{},group:{}",key.getName(),key.getGroup());
JobDataMap jobDataMap = jobExecutionContext.getJobDetail().getJobDataMap();
log.info("[jobDataMap] arg1:{},arg2:{}",jobDataMap.get("arg1"),jobDataMap.get("arg2"));
}
}
JobDetail
和 Trigger
package com.java4ye.demo.config;
import com.java4ye.demo.job.HelloWorldJob;
import org.quartz.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author Java4ye
* @date 2021/1/9 10:48
* @微信公众号: Java4ye
* @GitHub https://github.com/RyzeYang
* @博客 https://blog.csdn.net/weixin_40251892
*/
@Configuration
public class QuartzConfig {
@Bean
public JobDetail myJobDetail() {
return JobBuilder.newJob(HelloWorldJob.class)
.withIdentity("HelloWorldJob", "HelloWorldJob")
//JobDataMap可以给任务execute传递参数
.usingJobData("arg1", "Hello")
.usingJobData("arg2", "World")
.storeDurably()
.build();
}
@Bean
public Trigger myTrigger() {
return TriggerBuilder.newTrigger()
.forJob(myJobDetail())
.withIdentity("Hello World Job TRIGGER", "TRIGGER GROUP1")
.usingJobData("arg11","TRIGGER-arg11")
.usingJobData("arg1","TRIGGER-arg1")
.startNow()
//.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(5).repeatForever())
.withSchedule(CronScheduleBuilder.cronSchedule("0/10 * * * * ?"))
.build();
}
}
spring:
datasource:
url: jdbc:mysql://192.168.80.128:3306/yang?useSSL=false&useUnicode=true&characterEncoding=utf-8
username: java4ye
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
quartz:
jdbc:
# 这里有 三个选项 always(每次都帮你创建表) never(自己手动建表) embedded 默认的
initialize-schema: always
#持久化到数据库方式
job-store-type: jdbc
properties:
org:
quartz:
scheduler:
instanceName: MysqlScheduler
instanceId: AUTO
startupDelay: 10
jobStore:
class: org.quartz.impl.jdbcjobstore.JobStoreTX
driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
tablePrefix: QRTZ_
isClustered: true
clusterCheckinInterval: 10000
useProperties: false
threadPool:
class: org.quartz.simpl.SimpleThreadPool
#线程数 一个任务使用一个线程
threadCount: 10
threadPriority: 5
threadsInheritContextClassLoaderOfInitializingThread: true
这里博主有个疑问… 这个初始化表结构的 embedded
(内嵌的) 要怎么理解,它是默认的选项.
于是乎…开始折腾了
看看 embedded
等操作.
按照图中四个步骤操作
ctrl 键 + 鼠标滚轮
放大图片 (按住 alt 键 有放大镜功能), 然后点击 quartzDataSourceInitializer
,双击或者按F4
可以跳转到源码处 (看这个名字应该是初始化的,先进来看看有没有找错)按下 F7 进去, 再进去 super(dataSource, resourceLoader);
方法可以看到下图
注意这里有个 @PostConstruct
@PostConstruct注解的方法将会在依赖注入完成后被自动调用。
Constructor >> @Autowired >> @PostConstruct
所以我们直接在这里打个断点
直接进入到 isEnabled
方法 , 可以看到下图 : 由于我们配置的是 Always
quartz:
jdbc:
# 这里有 三个选项 always(每次都帮你创建表) never(自己手动建表) embedded 默认的
initialize-schema: always
所以 在进行逻辑或运算时直接返回 true .不会执行后面的 EmbeddedDatabaseConnection.isEmbedded(this.dataSource);
代码
从上图 debug 下来 可以看到 会去加载 这个 路径下的sql文件 ,最后
来到 jar 包中可以看到还有很多其他的sql文件
然后自己一步步 去 debug 下 EmbeddedDatabaseConnection.isEmbedded(this.dataSource);
这段代码就知道啦~ 博主这里说下结果了!
可以发现当你使用的数据库是内存型的如 H2 等时, 它 也会返回 true 即 isEnabled() 为 True, 然后会去执行创建 表格的sql语句,如上图中的sql文件
具体可以看看下图:
初始化表结构时,使用 embedded(内嵌的) 会去 看看db的类型是不是内嵌型的数据库或者说是内存型的 如常见的: h2
有兴趣的小伙伴还可以在debug过程中留意下 Spring boot 初始化 Bean 的一些操作