首先吐槽下,去年11月以实习生的身份来到现在的公司,到今年毕业转正,转正还没多久,社保卡都没发下来呢。实习这段时间没有怎么好好的学习工作吧,毕业后工资也不是很高,很多同学都比我高不少,无奈毕业季工作不好找也害怕去找就安稳的呆着,反正还有好多东西要学,工资也能养活自己,不用管家里要钱了吧。可是有的时候还是很不平衡,毕竟自我感觉自己的技术和很多工资比我高的同学相比,还算不赖吧!也算是对自己的考验吧,等把公司的东西都学会了自己的水平也提高了,再要高点,可能公司给多点的几率不大,那就再跳呗。
吐槽下自己,这一段时间太沉迷于游戏了,没有好好的利用时间整理自己的知识系统,有好多工作中领悟的东西都没及时记下来,到现在都忘记了。于是我打算从新来过,好好管理我的IT眼,好好工作学习。
好了,开始正题:Spring定时任务动态配置,我也有好多不懂的,既然来了就留下脚印,交流下把。吐槽下网上的好多动态配置定时任务的帖子,都是一样的,让我好是蛋疼。对比着来把。
首先是我们自己书写的类的Bean创建:
<bean id="logAdd2FARSTask" class="com.thid.business.task.LogAdd2FARSTask" >
<property name="scheduler" ref="schedulerFactory" />
<property name="personAlarmLogService">
<ref bean="personAlarmLogService"/>
</property>
</bean>
<bean id="logAdd2FARSTaskJob" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject">
<ref bean="logAdd2FARSTask" />
</property>
<property name="targetMethod">
<value>addStart</value>
</property>
<property name="concurrent" value="false"/>
</bean>
<bean id="logAdd2FARSTaskJobTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail">
<ref bean="logAdd2FARSTaskJob" />
</property>
<property name="cronExpression">
<value>0/10 * * * * ?</value>
</property>
</bean>
<bean id="schedulerFactory" class="org.springframework.scheduling.quartz.SchedulerFactoryBean" >
<property name="triggers" >
<list>
<ref bean="logAdd2FARSTaskJobTrigger" />
</list>
</property>
</bean>
<bean id="logAdd2FARSTask" class="com.thid.business.task.LogAdd2FARSTask" >
<property name="personAlarmLogService">
<ref bean="personAlarmLogService"/>
</property>
</bean>
<bean id="logAdd2FARSTaskJob" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject">
<ref bean="logAdd2FARSTask" />
</property>
<property name="targetMethod">
<value>addStart</value>
</property>
<property name="concurrent" value="false"/>
</bean>
<bean id="logAdd2FARSTaskJobTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail">
<ref bean="logAdd2FARSTaskJob" />
</property>
<property name="cronExpression">
<value>0/10 * * * * ?</value>
</property>
</bean>
<bean id="schedulerFactory" class="org.springframework.scheduling.quartz.SchedulerFactoryBean" >
<property name="triggers" >
<list>
<ref bean="logAdd2FARSTaskJobTrigger" />
</list>
</property>
</bean>
本来想弄个颜色把不同的地方标注起来,可是不太会用~说吧,两者的区别就在于第一个Bean中,动态配置的时候需要将schedulerFactory这个类注入到我们写的业务类中,注意观察下就可以发现,这个schedulerFactory就是我们代码最后的对所有定时任务进行管理的定时器工厂类,可以看下哦!之所以要向我们自己写的类中注入工厂类是因为我们要通过工厂类对我们要动态配置的定时任务进行管理。其实动态任务的实现就是通过工厂类对定时任务的cronExpression进行更改管理,从而实现动态配置的目的。下面看下Java代码中是如何配置:
public void setPersonAlarmLogService(PersonAlarmLogService personAlarmLogService) throws ParseException, SchedulerException {
this.personAlarmLogService = personAlarmLogService;
String triggerName = "logAdd2FARSTaskJobTrigger";
CronTriggerBean trigger = (CronTriggerBean)scheduler.getTrigger(triggerName, Scheduler.DEFAULT_GROUP);
if(trigger!=null){
SysParameter param = sysUserService.getSysParam();
String cronExpression = getCronExpressionFromDB(param);
trigger.setCronExpression(cronExpression);
}
}
/**
* 自定义定时器调度时间
* @param triggerName 触发器名称
* @throws Exception
*/
public void updateNotificationInterval(String triggerName,SysParameter sysParameter)
throws SchedulerException, ParseException {
// 得到trigger
CronTriggerBean trigger = (CronTriggerBean)scheduler.getTrigger(triggerName, Scheduler.DEFAULT_GROUP);
// 得到cron expression
if(trigger!=null){
String cronExpression = getCronExpressionFromDB(sysParameter);
String oldCronExpression = trigger.getCronExpression();
if(!oldCronExpression.equals(cronExpression)){
// 设置trigger的时间规则
trigger.setCronExpression(cronExpression);
// 重置job
scheduler.rescheduleJob(triggerName, Scheduler.DEFAULT_GROUP, trigger);
}
System.out.println(trigger.getCronExpression());
}
}
public String getCronExpressionFromDB(SysParameter sysParameter){
String dbCronExpression = null;
if(sysParameter==null){
dbCronExpression = "0 0 0 * * * ?";
}else{
String hour =sysParameter.getRev7();
dbCronExpression = "0"+" "+"0"+" "+"*/"+hour+" "+"*"+" "+"*"+" "+"?";
}
return dbCronExpression;
}
首先如果我们不需要在服务器启动的时候去数据库读定时任务的执行时间的话,那么第一个方法可以直接跳过,但是大多数向做动态定时任务的都应该会在启动的时候去读数据库。简单做下介绍,这个方法是personAlarmLogService的set方法,在程序启动加载到这里的时候,会通过我们注入的scheduler的getTrigger查找名为logAdd2FARSTaskJobTrigger的触发器,如果找到了就从数据库中查询我们添加的执行方案,然后通过setCronExpression方法将执行方案设置到我们查找的trigger中,就形成了启动时的动态配置。
然后我们每次更改时间的时候,都调用下更改触发器的方法,在我的代码里是updateNotificationInterval方法。同样是通过名称获得trigger,然后setCornExpression,都进行完了之后别忘了从新启动定时任务,也就是这行代码
scheduler.rescheduleJob(triggerName, Scheduler.DEFAULT_GROUP, trigger);
还有就是这个类要继承CronTriggerBean类.
---------------------以下是我遇到的问题求解答--------------------
1. 网上的例子启动的时候就从数据库读取规则是不用设置时间规则,也就是下面这段不用配置,可是我把他注释掉会报错。求解答
<property name="cronExpression">
<value>0/10 * * * * ?</value>
</property>
2.为什么我在工厂类的LIST中将这个触发器注释掉,会报错,然后再把下面代码注释掉就不报错了?这个service就是我在启动时设置定时任务的cronExpression的方法。
<property name="personAlarmLogService">
<ref bean="personAlarmLogService"/>
</property>
希望走过路过的兄弟姐妹们帮着小弟解答下问题,代码有点水见谅。