1、Quartz在Spring中的简单配置
Spring配置文件quartz.xml:
在上面的配置中设定:
① targetMethod: 指定需要定时执行scheduleInfoAction中的test()方法
② concurrent:对于相同的JobDetail,当指定多个Trigger时, 很可能第一个job完成之前,第二个job就开始了。指定concurrent设为false,多个job不会并发运行,第二个job将不会在第一个job完成之前开始。
③ cronExpression:0/10 * * * * ?表示每10秒执行一次,具体可参考附表。
④ triggers:通过再添加其他的ref元素可在list中放置多个触发器。
scheduleInfoAction中的simpleJobTest()方法
注意:此方法没有参数,如果scheduleInfoAction有两个方法test()和test(String argument),则spring只会去执行无参的test().
2、Quartz在Spring中动态设置cronTrigger方法一
(1)、Spring配置文件quartz.xml:
(2)、类ScheduleInfoAction:
3、Quartz在Spring中动态设置cronTrigger方法二
在2中我们已经能够实现动态配置cronException,但是我们依然需要设定一个默认的cronException:
如果我们拿掉它,则容器(如Jboss)会报错。
实际上我们希望容器启动时就去数据库获得dbCronException,而不需要再初始化一个cronException。观察CronTriggerBean,需要初始化cronException,我们可以创建类InitCronTrigger继承CronTriggerBean,从DB中获得数据初始化cronException,这样问题就解决了。
(1)、Spring配置文件quartz.xml:
(2)、类InitCronTrigger
注意:在注入scheduleInfoManager属性的时候,我们可以去读取DB任务时间(之所以放在setter方法中,是因为需要在设置scheduleInfoManager后进行getCronExpressionFromDB(),否则,也可以①②逻辑把放在类的构造函数中).
注意InitializingCronTrigger必须extends CronTriggerBean.
Spring配置文件quartz.xml:
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
- <beans>
- <bean id="scheduleInfoService" class="com.erry.tntops.web.task.ScheduleInfoService">
- <property name="scheduler" ref="schedulerFactory"/>
- </bean>
- <bean id="jobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
- <property name="targetObject" ref="scheduleInfoService"/>
- <property name="targetMethod" value="test"/>
- <property name="concurrent" value="false"/>
- </bean>
- <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean" >
- <property name="jobDetail" ref="jobDetail"/>
- <property name="cronExpression">
- <value>0/10 * * * * ?</value>
- </property>
- </bean>
- <bean id="schedulerFactory" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
- <property name="triggers">
- <list>
- <ref local="cronTrigger"/>
- </list>
- </property>
- </bean>
- </beans>
在上面的配置中设定:
① targetMethod: 指定需要定时执行scheduleInfoAction中的test()方法
② concurrent:对于相同的JobDetail,当指定多个Trigger时, 很可能第一个job完成之前,第二个job就开始了。指定concurrent设为false,多个job不会并发运行,第二个job将不会在第一个job完成之前开始。
③ cronExpression:0/10 * * * * ?表示每10秒执行一次,具体可参考附表。
④ triggers:通过再添加其他的ref元素可在list中放置多个触发器。
scheduleInfoAction中的simpleJobTest()方法
注意:此方法没有参数,如果scheduleInfoAction有两个方法test()和test(String argument),则spring只会去执行无参的test().
- public void test() {
- log.warn("uh oh, Job is scheduled !'" + "' Success...");
- }
2、Quartz在Spring中动态设置cronTrigger方法一
(1)、Spring配置文件quartz.xml:
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
- <beans>
- <bean id="scheduleInfoAction" class="com.erry.tntops.web.task.ScheduleInfoAction">
- <property name="scheduler" ref="schedulerFactory"/>
- <!-- ref中的emsService是xml中配置的bean的id -->
- <property name="emsService" ref="emsService"/>
- </bean>
- <bean id="jobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
- <property name="targetObject" ref="scheduleInfoAction"/>
- <property name="targetMethod" value="reScheduleJob"/>
- <property name="concurrent" value="false"/>
- </bean>
- <bean id="cronTrigger" class="com.erry.tntops.web.task.InitCronTrigger">
- <property name="jobDetail" ref="jobDetail"/>
- <property name="cronExpression">
- <value>0/10 * * * * ?</value>
- </property>
- </bean>
- <bean id="schedulerFactory" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
- <property name="triggers">
- <list>
- <ref local="cronTrigger"/>
- </list>
- </property>
- </bean>
- </beans>
(2)、类ScheduleInfoAction:
- import org.apache.log4j.Logger;
- import org.quartz.Scheduler;
- import org.quartz.SchedulerException;
- import org.springframework.scheduling.quartz.CronTriggerBean;
- import java.text.ParseException;
- import java.util.Date;
- public class ScheduleInfoAction{
- Logger logger = Logger.getLogger(ScheduleInfoAction.class);
- private Scheduler scheduler;
- // 设值注入,通过setter方法传入被调用者的实例scheduler
- public void setScheduler(Scheduler scheduler) {
- this.scheduler = scheduler;
- }
- private EmsService emsService;
- public void setEmsService(EmsService emsService){
- this.emsService = emsService;
- }
- public void reScheduleJob() throws SchedulerException {
- // 运行时可通过动态注入的scheduler得到trigger,注意采用这种注入方式在有的项目中会有问题,如果遇到注入问题,可以采取在运行方法时候,获得bean来避免错误发生。
- CronTriggerBean trigger = (CronTriggerBean) scheduler.getTrigger("cronTrigger", Scheduler.DEFAULT_GROUP);
- logger.info("*********** trigger: " + trigger);
- String dbCronExpression = getCronExpressionFromDB();
- logger.info("*********** dbCronExpression: " + dbCronExpression);
- String originConExpression = trigger.getCronExpression();
- logger.info("*********** originConExpression: " + originConExpression);
- // 判断从DB中取得的任务时间(dbCronExpression)和现在的quartz线程中的任务时间(originConExpression)是否相等
- // 如果相等,则表示用户并没有重新设定数据库中的任务时间,这种情况不需要重新rescheduleJob
- if(!originConExpression.equalsIgnoreCase(dbCronExpression)){
- try{
- trigger.setCronExpression(dbCronExpression);
- scheduler.rescheduleJob("cronTrigger", Scheduler.DEFAULT_GROUP, trigger);
- } catch (ParseException e) {
- logger.error("------------------- ParseException Error! -------------------");
- e.printStackTrace();
- logger.error("-------------------------------------------------------------");
- }
- }
- //执行task
- logger.info("task start time: " + new Date());
- System.out.println("Task test success!");
- logger.info(" task end time: " + new Date());
- }
- private String getCronExpressionFromDB(){
- String sql = "select CRON from t_test_task_trigger where available = 1 and trigger_name = 'cronTrigger'";
- return emsService.getCron(sql);
- }
- }
3、Quartz在Spring中动态设置cronTrigger方法二
在2中我们已经能够实现动态配置cronException,但是我们依然需要设定一个默认的cronException:
- <property name="cronExpression">
- <value>0/10 * * * * ?</value>
- </property>
如果我们拿掉它,则容器(如Jboss)会报错。
实际上我们希望容器启动时就去数据库获得dbCronException,而不需要再初始化一个cronException。观察CronTriggerBean,需要初始化cronException,我们可以创建类InitCronTrigger继承CronTriggerBean,从DB中获得数据初始化cronException,这样问题就解决了。
(1)、Spring配置文件quartz.xml:
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
- <beans>
- <bean id="scheduleInfoAction" class="wym.task.ScheduleInfoAction">
- <property name="scheduler" ref="schedulerFactory"/>
- <property name="emsService" ref="EmsService"/>
- </bean>
- <bean id="jobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
- <property name="targetObject" ref="scheduleInfoAction"/>
- <property name="targetMethod" value="reScheduleJob"/>
- <!-- concurrent设为false,多个job不会并发运行 -->
- <property name="concurrent" value="false"/>
- </bean>
- <bean id="cronTrigger" class="wym.task.InitCronTrigger">
- <property name="jobDetail" ref="jobDetail"/>
- <!--<property name="cronExpression">-->
- <!--<value>0/30 * * * * ?</value>-->
- <!--</property>-->
- <property name="emsService" ref="EmsService"/>
- </bean>
- <bean id="schedulerFactory" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
- <property name="triggers">
- <list>
- <ref local="cronTrigger"/>
- </list>
- </property>
- </bean>
- </beans>
(2)、类InitCronTrigger
注意:在注入scheduleInfoManager属性的时候,我们可以去读取DB任务时间(之所以放在setter方法中,是因为需要在设置scheduleInfoManager后进行getCronExpressionFromDB(),否则,也可以①②逻辑把放在类的构造函数中).
注意InitializingCronTrigger必须extends CronTriggerBean.
- import com.erry.tntops.ems.service.EmsService;
- import org.springframework.scheduling.quartz.CronTriggerBean;
- import java.io.Serializable;
- import java.text.ParseException;
- public class InitCronTrigger extends CronTriggerBean implements Serializable {
- private EmsService emsService;
- public void setEmsService(EmsService emsService) throws ParseException {
- this.emsService = emsService;
- String cronException = getCronExceptionDB();
- setCronExpression(cronException);
- }
- private String getCronExceptionDB(){
- String sql = "select CRON from t_test_task_trigger where available = 1 and trigger_name = 'cronTrigger'";
- System.out.println("*****" + sql);
- return emsService.getCron(sql);
- }
- }