spring3.2.0 quartz-2.2.1 整合 实现动态定时任务

spring3.2.0 quartz-2.2.1 实现动态定时任务
    spring 和 quartz的整合很简单,但是实现动态定时任务却有一点麻烦,下面详细介绍一下 spring3.2.0和quzrtz2.2.1 的整合 实现定时任务的的动态加载

项目整体结构介绍:

    需要的jar以及整体结构如下  
spring3.2.0 quartz-2.2.1 整合 实现动态定时任务_第1张图片 spring3.2.0 quartz-2.2.1 整合 实现动态定时任务_第2张图片

类介绍:
AutoJobDTO.java 里面就是一些job的信息,jobname groupname等;JobAction.java 自动任务调度;JobManager.java 任务的管理(新增,删除,暂停等 这里举例新增的,其余的可以看官网API)JobService.java 动态造数据,调用 JobManager 添加任务;  quartz 中的 job如何自动注入spring容器托管的对象?MyJobFactory.java  这个类可以为大家说明; TestService.java 这个类就用来测试一下注入;


源代码:

AutoJobDTO.java 
package quartz;
/**
 * 任务信息
 * @author Administrator
 *
 */
public class AutoJobDTO {
	private String job_id;	
	private String job_name;	
	private String job_group;
	private String job_time;    {get set ....}

JobAction.java 

package quartz;
import javax.annotation.Resource;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;

//@DisallowConcurrentExecution//有状态的任务需要加上这个注解
public class JobAction implements Job {

	@Autowired
	private TestService testService;
	{get set ...}
	@Override
	public void execute(JobExecutionContext arg0) throws JobExecutionException {
		System.out.println("任务成功运行------");
		AutoJobDTO detailInfo = (AutoJobDTO)arg0.getMergedJobDataMap().get("scheduleJob");
        System.out.println("任务名称 = [" + detailInfo.getJob_name()+ "]");
        if(testService==null){
        	System.out.println("注入不成功------");
        }else{
        	System.out.println("注入成功------");
        	testService.add();
        }
		
	}

}

JobManager.action

package quartz;
import java.text.ParseException;
import javax.annotation.Resource;
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;

public class JobManager {

	
 	/* 当初我初始化的是  SchedulerFactoryBean schedulerFactoryBean;  这样是注入不进去的 报下面的错
	   nested exception is org.springframework.beans.factory.BeanNotOfRequiredTypeException:
	   Bean named 'schedulerFactoryBean' must be of 
	   type [org.springframework.scheduling.quartz.SchedulerFactoryBean], 
	   but was actually of type [org.quartz.impl.StdScheduler>]
	   看spring源码可以知道,其实spring得到的是一个工厂bean,得到的不是它本身,而是它负责创建的org.quartz.impl.StdScheduler对象            所以要使用Scheduler对象
	*/
    @Resource
    private Scheduler scheduler ;
    
	public Scheduler getScheduler() {
		return scheduler;
	}

	public void setScheduler(Scheduler scheduler) {
		this.scheduler = scheduler;
	}

	/**
	 * 添加一个定时任务
	 */
	public  void addJob(AutoJobDTO job,Class classz) throws SchedulerException  {
		  //这里获取任务信息数据
 			TriggerKey triggerKey = TriggerKey.triggerKey(job.getJob_name(), job.getJob_group());
			CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
			if(trigger==null){
				System.out.println("trigger is null----");
				//不存在,创建一个
				JobDetail jobDetail = JobBuilder.newJob(classz).withIdentity(job.getJob_name(), job.getJob_group()).build();
				jobDetail.getJobDataMap().put("scheduleJob", job);
				//表达式调度构建器
				CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getJob_time());
				//按新的cronExpression表达式构建一个新的trigger
				trigger = TriggerBuilder.newTrigger().withIdentity(job.getJob_name(), job.getJob_group()).withSchedule(scheduleBuilder).build();
				scheduler.scheduleJob(jobDetail,trigger);
			}else{
				// Trigger已存在,那么更新相应的定时设置
				//表达式调度构建器
				CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getJob_time());
				//按新的cronExpression表达式重新构建trigger
				trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
				//按新的trigger重新设置job执行
				scheduler.rescheduleJob(triggerKey, trigger);
			}
	}
	/**
	 * 启动所有定时任务
	 */
	public  void startJobs() {
		try {
			scheduler.start();
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
	}
}

JobService.java

package quartz;

import javax.annotation.Resource;

import org.quartz.SchedulerException;



/**
 * 调用job
 * @author Administrator
 *
 */
public class JobService {
	@Resource
	private JobManager jobManager;
	
	public JobManager getJobManager() {
		return jobManager;
	}
	public void setJobManager(JobManager jobManager) {
		this.jobManager = jobManager;
	}
	
	/**
	 * 初始化定时任务
	 * @throws SchedulerException 
	 */
	public void loadJobInit() throws SchedulerException{
		    System.out.println("init---");
 			AutoJobDTO job = new AutoJobDTO();
			job.setJob_id("Id1");
			job.setJob_name("Name1");
			job.setJob_group("linGroup");
			job.setJob_time("0/30 * * * * ?");
		       jobManager.addJob(job, JobAction.class);
		        jobManager.startJobs();
	}
	
}
TestService.java

package quartz;

public class TestService {

	
	public void add(){
		System.out.println("注入测试----");
	}
}
MyJobFactory.java
这个类是重写 AdaptableJobFactory 的createJobInstance这个方法,具体原因参见: http://blog.csdn.net/linlinv3/article/details/49450775

package spring;

import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.scheduling.quartz.AdaptableJobFactory;

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

或者这么写也可以,因为有情况说上述方法打包后 注入不进去
package com.summoner.service.job.impl;

import javax.annotation.Resource;

import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.scheduling.quartz.AdaptableJobFactory;


public class MyJobFactory extends AdaptableJobFactory implements ApplicationContextAware {

	//这个对象Spring会帮我们自动注入进来,也属于Spring技术范畴.
//	@Resource
//	private AutowireCapableBeanFactory capableBeanFactory;
	  
	ApplicationContext applicationContext;
	
//	public AutowireCapableBeanFactory getCapableBeanFactoryYunZong() {
//		return capableBeanFactoryYunZong;
//	}
//
//
//	public void setCapableBeanFactoryYunZong(
//			AutowireCapableBeanFactory capableBeanFactoryYunZong) {
//		this.capableBeanFactoryYunZong = capableBeanFactoryYunZong;
//	}


	@Override
	protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
	    //调用父类的方法
	    Object jobInstance = super.createJobInstance(bundle);
	    
	    //进行注入,这属于Spring的技术,不清楚的可以查看Spring的API.
	   AutowireCapableBeanFactory aaa = applicationContext.getAutowireCapableBeanFactory();
	   aaa.autowireBeanProperties(jobInstance, AutowireCapableBeanFactory.AUTOWIRE_BY_NAME, false);
//	    applicationContext.getAutowireCapableBeanFactory().autowireBean(jobInstance);
//	    capableBeanFactoryYunZong.autowireBean(jobInstance);
	    return jobInstance;
	  }


	@Override
	public void setApplicationContext(ApplicationContext applicationContext)
			throws BeansException {
		this.applicationContext = applicationContext;
		
	}
	}



spring 配置文件:



    
       
    
    
    	 
       
     
    


然后启动程序就能看到定时任务的加载,console输出
spring3.2.0 quartz-2.2.1 整合 实现动态定时任务_第3张图片


 

你可能感兴趣的:(java)