pigwing

导航

 

上一篇博文地址 Quartz与Spring整合进行热部署的实现

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;
	}

	
}

posted on 2011-07-12 10:47  pigwing  阅读(2978)  评论(1编辑  收藏  举报