springmvc框架已经很成熟了,所以引入的jar包我就不详细说了,百度有很多我先简单描述我说的主要功能:
由spring的Quartz在启动之后,扫描数据库的任务,使用场景,需要动态添加定时任务如:定时启动某智能家居设备,定时抽奖等,
这里顺便附上一份第一种quartz的xml方式: (他支持的注解也可以是 {@Scheduled(cron = "0/10 * * * * *")}这种形式)
<bean id="quartzScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="syncAppDayJobCronTrigger" />
</list>
</property>
</bean>
<!-- CORE的所有任务-->
<bean id="coreJob" class="live.mica.core.biz.job.CoreJob"/>
<!-- 定时把每天日期放入缓存 -->
<bean id="syncAppDayJob" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject">
<ref bean="coreJob"/>
</property>
<property name="targetMethod">
<value>syncAppDay</value>
</property>
<property name="concurrent" value="false">
</property>
</bean>
<bean id="syncAppDayJobCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail">
<ref bean="syncAppDayJob" />
</property>
<property name="cronExpression">
<!-- 每天0点5分 -->
<value>0/10 * * * * ?</value>
</property>
</bean>
live.mica.core.biz.job.CoreJob
@Service
public class CoreJob {
/**
* 定时把每天日期放入缓存
*/
public void syncAppDay() {
log.info("sync syncAppDay info start...");
try {
} catch (Exception ex) {
log.error("fail to sync syncAppDay info.", ex);
} finally {
log.info("sync syncAppDay info end.");
}
}
}
其中需要注意的地方我用颜色标了出来,相同的颜色表示有对应关系。
很显然,每个任务都是提前在xml里配置的,没办法动态灵活添加启用,
在15年使用了数据库的注解,项目就是智能家具的定时功能,但在17年的时候用spring boot做后台的时候(是开源框架),使用了配置大于默认的注解,而且很规范,就想移植到当前的核心项目中,但是问题来了spring boot没有任何声明配置,就能使用这个定时,而我在普通项目的时候是有很多配置的,网上找也很片面,所以趁现在移植项目,写一个比较傻瓜的文档(个人比较倾向傻瓜式code代码)
spring的jar包我就不说了,直接进入正题:
个人理解技术的主要思想:
spring 本身的定时很好,但是如果要加上动态添加随意启动的效果,需要比第一种方式多一个操作:
和 spring的job 公用一个任务工厂,当项目启动时,去初始化定时器,然后把数据库的定时数据 构建到spring的job中
红色部分就是需要重点xml配置的地方:
<!--添加quartz支持 -->
<bean id="schedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean" />
<!--加载可执行的任务-->
<bean id="scheduleJobService" class="live.mica.core.quartz.service.ScheduleJobService" init-method="init" />
live.mica.core.quartz.service.ScheduleJobService:
@Service
public class ScheduleJobService {
@Autowired
private Scheduler scheduler;
private static final String CRON_DATE_FORMAT = "ss mm HH dd MM ? yyyy";
/**
* 项目启动时,初始化定时器
*/
@PostConstruct
public void init(){
List<ScheduleJobEntity> scheduleJobList = new arrayList<>();//查数据库
for(ScheduleJobEntity scheduleJob : scheduleJobList){
CronTrigger cronTrigger = ScheduleUtils.getCronTrigger(scheduler, scheduleJob.getJobId());
//如果不存在,则创建
if(cronTrigger == null) {
//构建job信息
}else {
//更新定时任务
}
}
}
}
这是项目中移植的全部代码,xml里的就上图的两句。
虽然代码多了点,但是结构比较清晰,支持连接池,分布式,虽然自己想写的更详细些,写文档的时候发现大部分都是代码,核心其实很简单,步骤很少。代码不好上传,sorry~