(一)spring3.2.0 quartz-2.2.1 整合 实现动态定时任务 解决service为null问题

来源:互联网 发布:买情趣 淘宝 编辑:程序博客网 时间:2024/05/18 21:39
spring3.2.0 quartz-2.2.1 实现动态定时任务
    spring 和 quartz的整合很简单,但是实现动态定时任务却有一点麻烦,下面详细介绍一下 spring3.2.0和quzrtz2.2.1 的整合 实现定时任务的的动态加载

项目整体结构介绍:

    需要的jar以及整体结构如下  


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


源代码:

AutoJobDTO.java 
[java] view plain copy
 print?
  1. package quartz;  
  2. /** 
  3.  * 任务信息 
  4.  * @author Administrator 
  5.  * 
  6.  */  
  7. public class AutoJobDTO {  
  8.     private String job_id;    
  9.     private String job_name;      
  10.     private String job_group;  
  11.     private String job_time;    {get set ....}  

JobAction.java 

[java] view plain copy
 print?
  1. package quartz;  
  2. import javax.annotation.Resource;  
  3. import org.quartz.Job;  
  4. import org.quartz.JobExecutionContext;  
  5. import org.quartz.JobExecutionException;  
  6. import org.springframework.beans.factory.annotation.Autowired;  
  7.   
  8. //@DisallowConcurrentExecution//有状态的任务需要加上这个注解  
  9. public class JobAction implements Job {  
  10.   
  11.     @Autowired  
  12.     private TestService testService;  
  13.     {get set ...}  
  14.     @Override  
  15.     public void execute(JobExecutionContext arg0) throws JobExecutionException {  
  16.         System.out.println("任务成功运行------");  
  17.         AutoJobDTO detailInfo = (AutoJobDTO)arg0.getMergedJobDataMap().get("scheduleJob");  
  18.         System.out.println("任务名称 = [" + detailInfo.getJob_name()+ "]");  
  19.         if(testService==null){  
  20.             System.out.println("注入不成功------");  
  21.         }else{  
  22.             System.out.println("注入成功------");  
  23.             testService.add();  
  24.         }  
  25.           
  26.     }  
  27.   
  28. }  

JobManager.action

[java] view plain copy
 print?
  1. package quartz;  
  2. import java.text.ParseException;  
  3. import javax.annotation.Resource;  
  4. import org.quartz.CronScheduleBuilder;  
  5. import org.quartz.CronTrigger;  
  6. import org.quartz.JobBuilder;  
  7. import org.quartz.JobDetail;  
  8. import org.quartz.Scheduler;  
  9. import org.quartz.SchedulerException;  
  10. import org.quartz.TriggerBuilder;  
  11. import org.quartz.TriggerKey;  
  12.   
  13. public class JobManager {  
  14.   
  15.       
  16.     /* 当初我初始化的是  SchedulerFactoryBean schedulerFactoryBean;  这样是注入不进去的 报下面的错 
  17.        nested exception is org.springframework.beans.factory.BeanNotOfRequiredTypeException: 
  18.        Bean named 'schedulerFactoryBean' must be of  
  19.        type [org.springframework.scheduling.quartz.SchedulerFactoryBean],  
  20.        but was actually of type [org.quartz.impl.StdScheduler>] 
  21.        看spring源码可以知道,其实spring得到的是一个工厂bean,得到的不是它本身,而是它负责创建的org.quartz.impl.StdScheduler对象            所以要使用Scheduler对象 
  22.     */  
  23.     @Resource  
  24.     private Scheduler scheduler ;  
  25.       
  26.     public Scheduler getScheduler() {  
  27.         return scheduler;  
  28.     }  
  29.   
  30.     public void setScheduler(Scheduler scheduler) {  
  31.         this.scheduler = scheduler;  
  32.     }  
  33.   
  34.     /** 
  35.      * 添加一个定时任务 
  36.      */  
  37.     public  void addJob(AutoJobDTO job,Class classz) throws SchedulerException  {  
  38.           //这里获取任务信息数据  
  39.             TriggerKey triggerKey = TriggerKey.triggerKey(job.getJob_name(), job.getJob_group());  
  40.             CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);  
  41.             if(trigger==null){  
  42.                 System.out.println("trigger is null----");  
  43.                 //不存在,创建一个  
  44.                 JobDetail jobDetail = JobBuilder.newJob(classz).withIdentity(job.getJob_name(), job.getJob_group()).build();  
  45.                 jobDetail.getJobDataMap().put("scheduleJob", job);  
  46.                 //表达式调度构建器  
  47.                 CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getJob_time());  
  48.                 //按新的cronExpression表达式构建一个新的trigger  
  49.                 trigger = TriggerBuilder.newTrigger().withIdentity(job.getJob_name(), job.getJob_group()).withSchedule(scheduleBuilder).build();  
  50.                 scheduler.scheduleJob(jobDetail,trigger);  
  51.             }else{  
  52.                 // Trigger已存在,那么更新相应的定时设置  
  53.                 //表达式调度构建器  
  54.                 CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getJob_time());  
  55.                 //按新的cronExpression表达式重新构建trigger  
  56.                 trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();  
  57.                 //按新的trigger重新设置job执行  
  58.                 scheduler.rescheduleJob(triggerKey, trigger);  
  59.             }  
  60.     }  
  61.     /** 
  62.      * 启动所有定时任务 
  63.      */  
  64.     public  void startJobs() {  
  65.         try {  
  66.             scheduler.start();  
  67.         } catch (Exception e) {  
  68.             e.printStackTrace();  
  69.             throw new RuntimeException(e);  
  70.         }  
  71.     }  
  72. }  

JobService.java

[java] view plain copy
 print?
  1. package quartz;  
  2.   
  3. import javax.annotation.Resource;  
  4.   
  5. import org.quartz.SchedulerException;  
  6.   
  7.   
  8.   
  9. /** 
  10.  * 调用job 
  11.  * @author Administrator 
  12.  * 
  13.  */  
  14. public class JobService {  
  15.     @Resource  
  16.     private JobManager jobManager;  
  17.       
  18.     public JobManager getJobManager() {  
  19.         return jobManager;  
  20.     }  
  21.     public void setJobManager(JobManager jobManager) {  
  22.         this.jobManager = jobManager;  
  23.     }  
  24.       
  25.     /** 
  26.      * 初始化定时任务 
  27.      * @throws SchedulerException  
  28.      */  
  29.     public void loadJobInit() throws SchedulerException{  
  30.             System.out.println("init---");  
  31.             AutoJobDTO job = new AutoJobDTO();  
  32.             job.setJob_id("Id1");  
  33.             job.setJob_name("Name1");  
  34.             job.setJob_group("linGroup");  
  35.             job.setJob_time("0/30 * * * * ?");  
  36.                jobManager.addJob(job, JobAction.class);  
  37.                 jobManager.startJobs();  
  38.     }  
  39.       
  40. }  
TestService.java

[java] view plain copy
 print?
  1. package quartz;  
  2.   
  3. public class TestService {  
  4.   
  5.       
  6.     public void add(){  
  7.         System.out.println("注入测试----");  
  8.     }  
  9. }  
MyJobFactory.java
这个类是重写 AdaptableJobFactory 的createJobInstance这个方法,具体原因参见:http://blog.csdn.net/linlinv3/article/details/49450775

[java] view plain copy
 print?
  1. package spring;  
  2.   
  3. import org.quartz.spi.TriggerFiredBundle;  
  4. import org.springframework.beans.factory.annotation.Autowired;  
  5. import org.springframework.beans.factory.config.AutowireCapableBeanFactory;  
  6. import org.springframework.scheduling.quartz.AdaptableJobFactory;  
  7.   
  8. public class MyJobFactory extends AdaptableJobFactory {  
  9.   
  10.       //这个对象Spring会帮我们自动注入进来,也属于Spring技术范畴.  
  11.       @Autowired  
  12.       private AutowireCapableBeanFactory capableBeanFactory;  
  13.         
  14.       protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {  
  15.         //调用父类的方法  
  16.         Object jobInstance = super.createJobInstance(bundle);  
  17.         //进行注入,这属于Spring的技术,不清楚的可以查看Spring的API.  
  18.         capableBeanFactory.autowireBean(jobInstance);  
  19.         return jobInstance;  
  20.       }  
  21.     }  

或者这么写也可以,因为有情况说上述方法打包后 注入不进去
[java] view plain copy
 print?
  1. package com.summoner.service.job.impl;  
  2.   
  3. import javax.annotation.Resource;  
  4.   
  5. import org.quartz.spi.TriggerFiredBundle;  
  6. import org.springframework.beans.BeansException;  
  7. import org.springframework.beans.factory.config.AutowireCapableBeanFactory;  
  8. import org.springframework.context.ApplicationContext;  
  9. import org.springframework.context.ApplicationContextAware;  
  10. import org.springframework.scheduling.quartz.AdaptableJobFactory;  
  11.   
  12.   
  13. public class MyJobFactory extends AdaptableJobFactory implements ApplicationContextAware {  
  14.   
  15.     //这个对象Spring会帮我们自动注入进来,也属于Spring技术范畴.  
  16. //  @Resource  
  17. //  private AutowireCapableBeanFactory capableBeanFactory;  
  18.         
  19.     ApplicationContext applicationContext;  
  20.       
  21. //  public AutowireCapableBeanFactory getCapableBeanFactoryYunZong() {  
  22. //      return capableBeanFactoryYunZong;  
  23. //  }  
  24. //  
  25. //  
  26. //  public void setCapableBeanFactoryYunZong(  
  27. //          AutowireCapableBeanFactory capableBeanFactoryYunZong) {  
  28. //      this.capableBeanFactoryYunZong = capableBeanFactoryYunZong;  
  29. //  }  
  30.   
  31.   
  32.     @Override  
  33.     protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {  
  34.         //调用父类的方法  
  35.         Object jobInstance = super.createJobInstance(bundle);  
  36.           
  37.         //进行注入,这属于Spring的技术,不清楚的可以查看Spring的API.  
  38.        AutowireCapableBeanFactory aaa = applicationContext.getAutowireCapableBeanFactory();  
  39.        aaa.autowireBeanProperties(jobInstance, AutowireCapableBeanFactory.AUTOWIRE_BY_NAME, false);  
  40. //      applicationContext.getAutowireCapableBeanFactory().autowireBean(jobInstance);  
  41. //      capableBeanFactoryYunZong.autowireBean(jobInstance);  
  42.         return jobInstance;  
  43.       }  
  44.   
  45.   
  46.     @Override  
  47.     public void setApplicationContext(ApplicationContext applicationContext)  
  48.             throws BeansException {  
  49.         this.applicationContext = applicationContext;  
  50.           
  51.     }  
  52.     }  



spring 配置文件:

[java] view plain copy
 print?
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"  
  4.     xmlns:tx="http://www.springframework.org/schema/tx"  
  5.     xsi:schemaLocation="  
  6.        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd  
  7.        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd  
  8.        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd  
  9.        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd"  
  10.     >  
  11.     <context:component-scan base-package="quartz" />  
  12.     <bean id="testService"   class="quartz.TestService"></bean>     
  13.     <bean id="jobFactory" class="spring.MyJobFactory"></bean>  
  14.     <bean id="Scheduler"   class="org.springframework.scheduling.quartz.SchedulerFactoryBean">  
  15.         <property name="jobFactory" ref="jobFactory" />   
  16.     </bean>     
  17.     <bean id="jobManager" class="quartz.JobManager"> </bean>  
  18.     <bean id="JobService" class="quartz.JobService" init-method="loadJobInit"></bean>  
  19. </beans>  


然后启动程序就能看到定时任务的加载,console输出


阅读全文
0 0
原创粉丝点击