Spring的org.springframework.scheduling.quartz.JobDetailBean提供Job可序列化的实现(具体实现可查看源码)
此时.我们原来的job就可以继承QuartzJobBean,便会自动序列化到数据库,quartz的具体配置文件如下
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd" default-lazy-init="true"> <description>quartz配置</description> <!-- quartz使用的数据源配置 --> <bean id="quartzDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="${quartz.jdbc.driver}" /> <property name="url" value="${quartz.jdbc.url}" /> <property name="username" value="${quartz.jdbc.username}" /> <property name="password" value="${quartz.jdbc.password}" /> </bean> <!-- 另一个事务管理器, Jdbc单数据源事务 --> <bean id="quartzTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="quartzDataSource" /> </bean> <bean name="quartzScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="dataSource" ref="quartzDataSource"/> <property name="applicationContextSchedulerContextKey" value="applicationContext"/> <property name="configLocation" value="classpath:quartz.properties"/><!-- 这个是必须的,QuartzScheduler 延时启动,应用启动完后 QuartzScheduler 再启动 --> <property name="startupDelay" value="30"/><!-- 这个是可选,QuartzScheduler 启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了 --> <property name="overwriteExistingJobs" value="true"/> <property name="jobDetails" > <list> <ref bean="serverHealthJobDetail"/> </list> </property> </bean> <!-- 运行次数记录 --> <bean id="serverHealthJobDetail" class="org.springframework.scheduling.quartz.JobDetailBean"> <!--requestsRecovery属性为true,则当Quartz服务被中止后,再次启动任务时会尝试恢复执行之前未完成的所有任务--> <property name="requestsRecovery" value="true"/> <!-- 标识job是持久的,删除触发器的时候不被删除 --> <property name="durability" value="true"/> <property name="jobClass" value="cn.yzzn.hvac.quartz.job.ServerHealthJob"/> </bean> </beans>
我们看到<property name="applicationContextSchedulerContextKey" value="applicationContext"/>此标签
Spring会帮我们自动注入applicationContext.并非上一篇文章中,通过Spring的工具手动获取applicationContext.
ServerHealthJob代码如下
public abstract class JobSupport extends QuartzJobBean { private BuildingManager buildingManager; private PlcManager plcManager; private static Logger logger = LoggerFactory.getLogger(JobSupport.class); private ApplicationContext applicationContext; /** * 从SchedulerFactoryBean注入的applicationContext. */ public void setApplicationContext(ApplicationContext applicationContext) { this.applicationContext = applicationContext; } public <T> T getBean(String beanName, Class<T> clazz) { return this.applicationContext.getBean(beanName, clazz); } @Override protected void executeInternal(JobExecutionContext context) throws JobExecutionException { if (ObjectUtils.isNullOrEmptyString(buildingManager)) { buildingManager = getBean("buildingManager", BuildingManager.class); } if (ObjectUtils.isNullOrEmptyString(plcManager)) { plcManager = getBean("plcManager", PlcManager.class); } List<Building> buildingList = buildingManager.getBuildings(); int size = buildingList.size(); for (int i = 0; i < size; i++) { Building building = buildingList.get(i); Set<Plc> plcSet = building.getPlcs(); for (Plc plc : plcSet) { innerIter(building, plc, i, size); } } } public abstract void innerIter(Building building, Plc plc, int index, int size); } public class ServerHealthJob extends JobSupport { @Override public void innerIter(Building building, Plc plc, int index, int size) { // TODO Auto-generated method stub } }
ServerHealthJob就可以被Spring轻松的序列化到数据库.解决了上篇博文中繁琐的操作.
JobSupport是本人系统业务需求,同学们可自定义实现只要继承QuartzJobBean即刻.
数据库中已存在次jobDetail
TriggerManager也没多大变化
/** * Quartz Scheduler 管理类 * 不带groupName参数的方法都采用自动填充默认组的形式 Scheduler.DEFAULT_GROUP * @author PigWing * */ public class SchedulerManagerImpl implements SchedulerManager { private QuartzDao quartzDao; private Scheduler scheduler; private static Logger logger = LoggerFactory.getLogger(UserController.class); /*** * 增加一个触发器任务,采用默认组形式 */ public void addTrigger(String triggerName, String jobName, String cronExpression) throws SchedulerException, ParseException { addTrigger(triggerName, Scheduler.DEFAULT_GROUP, jobName, Scheduler.DEFAULT_GROUP, cronExpression); } /** * * 增加一个触发器任务 */ public void addTrigger(String triggerName, String triggerGroupName, String jobName, String jobGrourpName, String cronExpression) throws SchedulerException, ParseException { if(StringUtils.isEmpty(triggerName)) { throw new RuntimeException("triggerName can not be null"); } try { JobDetail jobDetail = scheduler.getJobDetail(jobName, jobGrourpName); if(jobDetail != null) { scheduler.addJob(jobDetail, true); CronTrigger cronTrigger = new CronTrigger(triggerName, triggerGroupName, jobDetail.getName(), jobGrourpName); cronTrigger.setCronExpression(cronExpression); scheduler.scheduleJob(cronTrigger); scheduler.rescheduleJob(cronTrigger.getName(), cronTrigger.getGroup(), cronTrigger); }else { logger.error("cant not find jobDetail: " + jobGrourpName); } }catch(SchedulerException e) { logger.error(e.getMessage()); throw e; } } /** * 返回所有触发器信息 */ public List<Map<String, Object>> getAllTriggers() { return quartzDao.getQuartzTriggers(); } /** * 停止触发器 */ public void parseTrigger(String triggerName, String groupName) throws SchedulerException { try { scheduler.pauseTrigger(triggerName, groupName); }catch(SchedulerException e) { logger.error(e.getMessage()); throw e; } } /** * 停止触发器,采用默认组形式 */ public void parseTrigger(String triggerName) throws SchedulerException { parseTrigger(triggerName, Scheduler.DEFAULT_GROUP); } /** * 重启触发器 */ public void resumeTrigger(String triggerName, String groupName) throws SchedulerException { try { scheduler.resumeTrigger(triggerName, groupName); }catch(SchedulerException e) { logger.error(e.getMessage()); throw e; } } /** * 重启触发器,采用默认组形式 */ public void resumeTrigger(String triggerName) throws SchedulerException { resumeTrigger(triggerName, Scheduler.DEFAULT_GROUP); } /** * 移除触发器 */ public boolean removeTrigger(String triggerName, String groupName) throws SchedulerException { try { parseTrigger(triggerName, groupName); return scheduler.unscheduleJob(triggerName, groupName); }catch(SchedulerException e) { logger.error(e.getMessage()); throw e; } } /** * 移除触发器,采用默认组形式 */ public boolean removeTrigger(String triggerName) throws SchedulerException { try { return removeTrigger(triggerName, Scheduler.DEFAULT_GROUP); }catch(SchedulerException e) { logger.error(e.getMessage()); throw e; } } /** * 返回所有的任务名称 */ public String[] getJobNames(String groupName) throws SchedulerException { return scheduler.getJobNames(groupName); } public String[] getJobNames() throws SchedulerException { return scheduler.getJobNames(Scheduler.DEFAULT_GROUP); } @Autowired public void setQuartzDao(QuartzDao quartzDao) { this.quartzDao = quartzDao; } @Autowired public void setScheduler(Scheduler scheduler) { this.scheduler = scheduler; } }
本文转自:http://www.cnblogs.com/pigwing/archive/2011/07/12/2104002.html