代码控制Quartz的启动和停止
2014-08-04 15:59
120 查看
Spring中如何使用Quartz就不必说了,这里说说如果动态设定cron。
这个要解决3个问题:
1.将用户输入转换为Cron表达式
2.安全的重启quartz
3.程序启动的时候,从数据库中读取cron(而非spring配置文件中写死的那个)。
因为derpvail急着用,所以先说第3个。
动态读取数据库中的Cron,作为CronTriggerBean的属性
从数据库中读取cron,需要做一个CronExpressionFactoryBean,它是一个Spring的FactoryBean,可以读取数据库,并创建一个CronExpression对象:
然后呢,就是吧这个CronExpression对象注入到CronTriggerBean,但是CronTriggerBean的setCronExpression方法是重载的,本人不知道如何注入重载方法,所以只好继承了CronTriggerBean,添加了一个setCron方法,一遍于Spring的注入:
然后就是在spring中配置这两个Bean了,和普通的quartz类似,只不过cronExpression属性改为了cron属性:
注意default-lazy-init="false",这样,quartz就可以在项目启动的时候,读取数据库中的cron了。
安全的重启quartz
貌似网上的文章都不太对,下面的这方法可以正常运行,在此之前,你应该把ApplicationContext注入,可以用ApplicationContextAware接口,也可以用@Autowired注解:
文章转载 http://cats-tiger.iteye.com/blog/440687
这个要解决3个问题:
1.将用户输入转换为Cron表达式
2.安全的重启quartz
3.程序启动的时候,从数据库中读取cron(而非spring配置文件中写死的那个)。
因为derpvail急着用,所以先说第3个。
动态读取数据库中的Cron,作为CronTriggerBean的属性
从数据库中读取cron,需要做一个CronExpressionFactoryBean,它是一个Spring的FactoryBean,可以读取数据库,并创建一个CronExpression对象:
public class CronFactoryBean implements FactoryBean { private static Logger logger = LoggerFactory.getLogger(CronFactoryBean.class); @Autowired @Qualifier("defaultFreq") private String defaultCron; /** * 用于取得CRON表达式. */ @Autowired(required = true) private CronManager cronManager; /** * 从数据库中取得CRON表达式,如果数据库中没有则取缺省值. * @see EmailConstants#DEFALUT_CRON */ @Override public Object getObject() throws Exception { //如何读取数据库,就省了 String cronEx = cronManager.getCronExpression(); if(StringUtils.isBlank(cronEx)) { return new CronExpression(defaultCron); } return new CronExpression(cronEx.trim()); } @SuppressWarnings("unchecked") @Override public Class getObjectType() { return CronExpression.class; } @Override public boolean isSingleton() { return true; } }
然后呢,就是吧这个CronExpression对象注入到CronTriggerBean,但是CronTriggerBean的setCronExpression方法是重载的,本人不知道如何注入重载方法,所以只好继承了CronTriggerBean,添加了一个setCron方法,一遍于Spring的注入:
/** * FIXME:因为目前不知道如何实现重载方法的注入,而<code>CronTrigger</code> * 的<code>setCronExpression</code>既可以用<code>CronExpression</code> * 对象作为参数也可以用String作为参数,这就产生了不确定性。所以,我们extends了 * <code>CronTriggerBean</code>,提供{@link #setCron(CronExpression)} * 方法,避免这种不确定性。 * @author Sam * */ public class CronTriggerBeanEx extends CronTriggerBean { /** * 调用父类的{@link CronTriggerBean#setCronExpression(CronExpression)} * 方法. */ public void setCron(CronExpression cronExpression) { this.setCronExpression(cronExpression); } }
然后就是在spring中配置这两个Bean了,和普通的quartz类似,只不过cronExpression属性改为了cron属性:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd"> <beans default-lazy-init="false"> <bean id="seismicEmailCronTrigger" class="datashare.email.admin.jobs.CronTriggerBeanEx"> <property name="jobDetail" ref="seismicEmailJobDetail" /> <property name="cron"> <bean class="datashare.email.admin.jobs.CronFactoryBean"> </property> </bean> </property> </bean> </beans>
注意default-lazy-init="false",这样,quartz就可以在项目启动的时候,读取数据库中的cron了。
安全的重启quartz
貌似网上的文章都不太对,下面的这方法可以正常运行,在此之前,你应该把ApplicationContext注入,可以用ApplicationContextAware接口,也可以用@Autowired注解:
@Autowired(required = true) private ApplicationContext ctx; /** * 如果cron改变,则重新启动Quartz任务。 * @param signCron 用户输入的CRON,你可以把它先存入数据库 * @throws ApplicationException 如果CRON无法解析,或原来的任务无法关闭,以及无法启动新任务. */ private void restartJobs(String signCron) { if(StringUtils.isBlank(signCron)) { logger.warn("CRON未设定。"); return; } //trim一下,难保没有空格 signCron = signCron.trim(); //得到trigger CronTrigger signCronTrigger = (CronTrigger) ctx.getBean("signEmailCronTrigger", CronTrigger.class); //如果频率都有变,则不必重新启动. if(signCron.equals(signCronTrigger.getCronExpression())) { logger.info("前兆和测震发送频率都未改变,Quartz不必重新启动."); return; } //下面是关键 //得到SchedulerFactoryBean的实例,注意beanName前面的&符号 SchedulerFactoryBean schedulerFactory = (SchedulerFactoryBean) ctx.getBean("&emailSchedulerFactory"); try { //重新设定trigger signCronTrigger.setCronExpression(signCron); schedulerFactory.destroy(); //关闭原来的任务 schedulerFactory.afterPropertiesSet(); //启动新的任务 logger.info("XXX任务启动成功."); } catch (ParseException e) { throw new ApplicationException("Cron表达式解析错误." + e.getMessage()); } catch (SchedulerException e) { e.printStackTrace(); throw new ApplicationException("关闭定时任务出现异常."); } catch (Exception e) { e.printStackTrace(); throw new ApplicationException("启动定时任务出现异常."); } } //我原来的代码和这个略有不同,这段代码没有调试过(在JE上编辑的),不过应该可以运行
文章转载 http://cats-tiger.iteye.com/blog/440687
相关文章推荐
- Windows服务代码控制安装卸载、启动停止
- 对NT服务型程序的控制代码。如安装服务、启动、停止服务、取服务状态等。
- java编程式控制quartz Scheduler 启动和停止,无法停止的问题解决
- 代码控制Selenium Server的启动和停止
- unity3D代码控制脚本的停止和启动
- 对NT服务型程序的控制代码。如安装服务、启动、停止服务、取服务状态等。
- java代码实现tomcat的启动和停止
- 使用批处理实现启动和停止服务的代码分析(net start&net stop)
- C#控制 计算机中“服务”的启动与停止
- mini2440启动代码分析之第七篇(ResetHandler和存储控制寄存器初始化)
- windows服务(安装/启动/卸载/停止)批处理代码
- 对s3c2440的存储控制及启动代码的理解
- shell控制lighttpd的启动停止
- 进程服务编写,与启动停止控制
- shell脚本控制jar的启动和停止
- shell脚本控制jar的启动和停止 - Linux,shell,脚本控制jar包启动停止 - language - ITeye论坛
- web页面控制windows服务的启动和停止
- C#控制 “MS-SQLServer”服务 的启动与停止
- 进程服务编写,与启动停止控制
- 如何使用命令行来控制IIS服务的启动和停止