Spring动态管理定时任务

发表时间:2018-01-18 12:36:15 浏览量( 44 ) 留言数( 0 )

学习目标:

1、Spring整合quartz的持久化管理

2、Spring的一个简单的工具类


学习过程:

    上一节课我们已经可以使用Spring整合Quartz,并且可以灵活得配置定时任务了。Spring对Job和Trigger都使用工厂类进行了代理得管理,如果你还想使用Quartz的Job,使用Quartz更多原始的功能,我们可以换一种整合方式的。我们需要代理SchedulerFactory,Spring提供了一个SchedulerFactoryBean类。在前面的课程里面我们提供Job是每一次都会new一个新类出来的,如果我们想在Job里面使用spring容器的对象,就需要重写jobFactory才行。

  定义自己的JobFactory

public class MyJobFactory extends AdaptableJobFactory {
	 //这个对象Spring会帮我们自动注入进来,也属于Spring技术范畴.
   @Autowired
   private AutowireCapableBeanFactory capableBeanFactory;
   
   protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
       //调用父类的方法
       Object jobInstance = super.createJobInstance(bundle);
       //进行注入,这属于Spring的技术,不清楚的可以查看Spring的API.
       capableBeanFactory.autowireBean(jobInstance);
       return jobInstance;
   }
}

配置文件使用这个JobFactory

	<bean id="jobFactory" class="com.quartzutil.MyJobFactory"></bean>
	<bean name="targetss"
		class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
		<property name="jobFactory" ref="jobFactory"></property>
		<property name="configLocation" value="classpath:quartz-job.properties" />
		<property name="dataSource" ref="dataSource"></property>
		<property name="triggers">
			<list>
				<ref bean="backupsimpleTrigger" />
				<!-- 添加一个新的任务 
				<ref bean="cronTrigger" />-->
			</list>
		</property>
	</bean>

quartz-job.properties

#Main Scheduler Settings  
org.quartz.scheduler.instanceName=quartzScheduler    
org.quartz.scheduler.threadsInheritContextClassLoaderOfInitializer=true  
org.quartz.scheduler.skipUpdateCheck=true  
org.quartz.scheduler.batchTriggerAcquisitionMaxCount=100  
  
org.quartz.threadPool.threadCount=10  
  
#Configure JDBC-JobStoreTX  
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
#org.quartz.jobStore.dataSource=myDS  
org.quartz.jobStore.tablePrefix=QRTZ_  

# Cluster
org.quartz.jobStore.isClustered=true  
org.quartz.jobStore.acquireTriggersWithinLock=true  
org.quartz.jobStore.clusterCheckinInterval = 30000


除了使用上节课使用注解和xml配置的任务外,为了更方便我们定义了一个工具类,用于动态的管理这些job,当然这个工具并不是很完美的。

@Component
public class QuartzUtil {

	@Autowired
	private SchedulerFactoryBean schedulerFactoryBean;
	
	@Autowired  
    private GlobalQuartzListener globalQuartzListener;
  

	public final static Logger logger = LoggerFactory.getLogger(QuartzUtil.class);

	private Scheduler scheduler;

	@PostConstruct
	public void init() {
		try {
			scheduler = schedulerFactoryBean.getScheduler();
			
			scheduler.getListenerManager().addJobListener(globalQuartzListener);

		} catch (SchedulerException e) {
			logger.error("error", e);
			e.printStackTrace();
		}
	}

	/**
	 * 添加一个新的工作任务
	 * 
	 * @param jobdetailManage
	 * @throws ClassNotFoundException
	 * @throws SchedulerException
	 */
	public void createJob(JobdetailManage jobdetailManage) throws ClassNotFoundException, SchedulerException {

		Class clazz = Class.forName(jobdetailManage.getTargetobject());

		JobDetail job = JobBuilder.newJob(clazz)
				.withIdentity(jobdetailManage.getJobname(), jobdetailManage.getJobgroup()).build();

		// Trigger the job to run now, and then every 40 seconds
		CronTrigger trigger = TriggerBuilder.newTrigger()
				.withIdentity(jobdetailManage.getTriggername(), jobdetailManage.getTriggergroup())
				.withSchedule(CronScheduleBuilder.cronSchedule(jobdetailManage.getCronexpression())).build();
		// Tell quartz to schedule the job using our trigger
		scheduler.scheduleJob(job, trigger);

		// 启动

	}

	public boolean deleteJob(String  name, String group) throws SchedulerException {
		scheduler.pauseJob(new JobKey(name, group));
		return scheduler.deleteJob(new JobKey(name, group));
	}
	
	public boolean deleteJobs(List<JobKey> jobKeys) throws SchedulerException{
		for(JobKey jobKey:jobKeys) {
			scheduler.pauseJob(jobKey);
		}
		return scheduler.deleteJobs(jobKeys);
	}

	public void pauseJob(String name, String group) throws SchedulerException {
		scheduler.pauseJob(new JobKey(name, group));
	}
	
	public void resumeJob(String name, String group) throws SchedulerException {
		scheduler.resumeJob(new JobKey(name, group));
	}

	/**
	 * 清除
	 */
	public void clearAllScheduler() {
		try {
			scheduler.clear();
		} catch (SchedulerException e) {
			logger.error("clearAllScheduler", e);
		}
	}

	/**
	 * 马上只执行一次任务
	 */
	public boolean executeOneceJob(String name, String group) {
		try {
			Calendar end = Calendar.getInstance();
			// SimpleTrigger实现Trigger接口的子接口。此处只指定了开始执行定时任务的时间,使用默认的重复次数(0次)和重复间隔
			TriggerBuilder<SimpleTrigger> simpleTriggerBuilder = TriggerBuilder.newTrigger().withIdentity("onceTrigger", "onceTriggerGroup")
					.forJob(new JobKey(name, group))
					.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(1).withRepeatCount(0));

			scheduler.scheduleJob(simpleTriggerBuilder.build());
			return true;
		} catch (SchedulerException e) {
			logger.error("executeOneceJob异常了。", e);
			return false;
		}
	}

}

使用了一个公共的触发器

@Component
public class GlobalQuartzListener implements JobListener {

	public final static Logger logger = LoggerFactory.getLogger(GlobalQuartzListener.class);


	public String getName() {

		return "GlobalQuartzListener";
	}

	public void jobToBeExecuted(JobExecutionContext context) {

		String jobName = context.getJobDetail().getKey().getName();
		String groupName = context.getJobDetail().getKey().getGroup();

		logger.info(jobName+"执行了。");

	}

	public void jobExecutionVetoed(JobExecutionContext context) {


	}

	public void jobWasExecuted(JobExecutionContext context, JobExecutionException jobException) {
		String jobName = context.getJobDetail().getKey().getName();

		logger.info(jobName+"执行了");
	}

}