Quartz的使用(解决quartz的job无法注入spring对象)

来源:互联网 发布:郑秀妍金泰妍关系知乎 编辑:程序博客网 时间:2024/05/23 14:57

1、说明:

spring3.1以下的版本必须使用quartz1.x系列,3.1以上的版本才支持quartz 2.x,不然会出错。至于原因,则是spring对于quartz的支持实现org.springframework.scheduling.quartz.CronTriggerBean继承了org.quartz.CronTrigger,在quartz1.x系列中org.quartz.CronTrigger是个类,而在quartz2.x系列中org.quartz.CronTrigger变成了接口,从而造成无法用spring的方式配置quartz的触发器(trigger)。

我使用的quartz版本是2.2.1 。

问题:
原来的Job是Spring自动扫描的,属性可以自动注入,现在换成使用单独的Quartz,属性不能注入了。

2、自定义一个类:

一般情况下,quartz的job中使用autowired注解注入的对象为空,这时候我们就要使用spring-quartz提供的AdaptableJobFactory类。

package com.yj.quartzjob;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 JobFactory extends AdaptableJobFactory {    @Autowired     private AutowireCapableBeanFactory capableBeanFactory;      @Override     protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {          //调用父类的方法          Object jobInstance = super.createJobInstance(bundle);          //进行注入          capableBeanFactory.autowireBean(jobInstance);          return jobInstance;      }}

3、Spring.XML的配置:

 <!-- quartz的定时任务的factorybean,配置其他config -->       <bean id="jobFactory" class="com.yj.quartzjob.JobFactory"></bean>      <bean id="schedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">          <property name="jobFactory" ref="jobFactory"></property>      </bean>  

4、简单的任务管理类:

package com.yj.until;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.Set;import org.quartz.CronScheduleBuilder;import org.quartz.CronTrigger;import org.quartz.DateBuilder;import org.quartz.DateBuilder.IntervalUnit;import org.quartz.Job;import org.quartz.JobBuilder;import org.quartz.JobDetail;import org.quartz.JobExecutionContext;import org.quartz.JobKey;import org.quartz.Scheduler;import org.quartz.SchedulerException;import org.quartz.SimpleScheduleBuilder;import org.quartz.Trigger;import org.quartz.TriggerBuilder;import org.quartz.TriggerKey;import org.quartz.impl.matchers.GroupMatcher;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;@Servicepublic class QuartzManager {    @Autowired    private Scheduler sched;    /**     * 增加一个job     * @param jobClass 任务实现类     * @param jobName 任务名称     *  @param jobGroupName 任务组名     * @param jobTime 时间表达式 (如:0/5 * * * * ? )     */    public  void addJob(Class<? extends Job> jobClass, String jobName,String jobGroupName,String jobTime) {        try {            //创建jobDetail实例,绑定Job实现类              //指明job的名称,所在组的名称,以及绑定job类            JobDetail jobDetail = JobBuilder.newJob(jobClass)                            .withIdentity(jobName, jobGroupName)//任务名称和组构成任务key                            .build();            //定义调度触发规则              //使用cornTrigger规则             Trigger trigger = TriggerBuilder.newTrigger()                        .withIdentity(jobName, jobGroupName)//触发器key                        .startAt(DateBuilder.futureDate(1, IntervalUnit.SECOND))                        .withSchedule(CronScheduleBuilder.cronSchedule(jobTime))                        .startNow().build();            //把作业和触发器注册到任务调度中            sched.scheduleJob(jobDetail, trigger);            // 启动            if (!sched.isShutdown()) {                sched.start();            }        } catch (Exception e) {            e.printStackTrace();        }    }    /**     * 增加一个job     * @param jobClass  任务实现类     * @param jobName  任务名称     * @param jobGroupName 任务组名     * @param jobTime  时间表达式 (这是每隔多少秒为一次任务)     */    public void addJob(Class<? extends Job> jobClass, String jobName,String jobGroupName,int jobTime){        addJob(jobClass,jobName,jobGroupName,jobTime,-1);    }    /**     * 增加一个job     * @param jobClass 任务实现类     * @param jobName  任务名称     * @param jobGroupName 任务组名     * @param jobTime  时间表达式 (这是每隔多少秒为一次任务)     * @param jobTimes  运行的次数 (<0:表示不限次数)     */    public void addJob(Class<? extends Job> jobClass, String jobName,String jobGroupName,int jobTime,int jobTimes){         try {             JobDetail jobDetail = JobBuilder.newJob(jobClass)                             .withIdentity(jobName, jobGroupName)//任务名称和组构成任务key                             .build();           //使用simpleTrigger规则             Trigger trigger=null;             if(jobTimes<0){                 trigger=TriggerBuilder.newTrigger().withIdentity(jobName, jobGroupName)                          .withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(1).withIntervalInSeconds(jobTime))                          .startNow().build();             }else{                 trigger=TriggerBuilder.newTrigger().withIdentity(jobName, jobGroupName)                          .withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(1).withIntervalInSeconds(jobTime).withRepeatCount(jobTimes))                          .startNow().build();             }            sched.scheduleJob(jobDetail, trigger);            if (!sched.isShutdown()) {                sched.start();            }        } catch (SchedulerException e) {            e.printStackTrace();        }    }    /**     * 修改 一个job的 时间表达式     * @param jobName     * @param jobGroupName     * @param jobTime     */    public void updateJob(String jobName,String jobGroupName,String jobTime){        try {            TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroupName);              CronTrigger trigger = (CronTrigger) sched.getTrigger(triggerKey);              trigger = trigger.getTriggerBuilder().withIdentity(triggerKey)                    .withSchedule(CronScheduleBuilder.cronSchedule(jobTime))                    .build();            //重启触发器            sched.rescheduleJob(triggerKey, trigger);        } catch (SchedulerException e) {            e.printStackTrace();        }      }    /**     * 删除任务一个job     * @param jobName 任务名称     * @param jobGroupName 任务组名     */    public  void deleteJob(String jobName,String jobGroupName) {        try {            sched.deleteJob(new JobKey(jobName, jobGroupName));        } catch (Exception e) {            e.printStackTrace();        }    }    /**     * 暂停一个job     * @param jobName     * @param jobGroupName     */    public void pauseJob(String jobName,String jobGroupName){        try {            JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);              sched.pauseJob(jobKey);        } catch (SchedulerException e) {            e.printStackTrace();        }     }    /**     * 恢复一个job     * @param jobName     * @param jobGroupName     */    public void resumeJob(String jobName,String jobGroupName){        try {            JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);            sched.resumeJob(jobKey);        } catch (SchedulerException e) {            e.printStackTrace();        }    }    /**     * 立即执行一个job     * @param jobName     * @param jobGroupName     */    public void runAJobNow(String jobName,String jobGroupName){        try {            JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);            sched.triggerJob(jobKey);        } catch (SchedulerException e) {            e.printStackTrace();        }    }    /**     * 获取所有计划中的任务列表     * @return     */    public List<Map<String,Object>> queryAllJob(){        List<Map<String,Object>> jobList=null;        try {             GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();               Set<JobKey> jobKeys = sched.getJobKeys(matcher);             jobList = new ArrayList<Map<String,Object>>();               for (JobKey jobKey : jobKeys) {                    List<? extends Trigger> triggers = sched.getTriggersOfJob(jobKey);                    for (Trigger trigger : triggers) {                        Map<String,Object> map=new HashMap<>();                      map.put("jobName",jobKey.getName());                      map.put("jobGroupName",jobKey.getGroup());                      map.put("description","触发器:" + trigger.getKey());                      Trigger.TriggerState triggerState = sched.getTriggerState(trigger.getKey());                        map.put("jobStatus",triggerState.name());                      if (trigger instanceof CronTrigger) {                            CronTrigger cronTrigger = (CronTrigger) trigger;                            String cronExpression = cronTrigger.getCronExpression();                            map.put("jobTime",cronExpression);                      }                        jobList.add(map);                    }                }          } catch (SchedulerException e) {            e.printStackTrace();        }          return jobList;      }    /**     * 获取所有正在运行的job     * @return     */    public List<Map<String,Object>> queryRunJon(){        List<Map<String,Object>> jobList=null;        try {            List<JobExecutionContext> executingJobs = sched.getCurrentlyExecutingJobs();            jobList = new ArrayList<Map<String,Object>>(executingJobs.size());              for (JobExecutionContext executingJob : executingJobs) {                  Map<String,Object> map=new HashMap<String, Object>();                  JobDetail jobDetail = executingJob.getJobDetail();                  JobKey jobKey = jobDetail.getKey();                  Trigger trigger = executingJob.getTrigger();                 map.put("jobName",jobKey.getName());                map.put("jobGroupName",jobKey.getGroup());                map.put("description","触发器:" + trigger.getKey());                Trigger.TriggerState triggerState = sched.getTriggerState(trigger.getKey());                  map.put("jobStatus",triggerState.name());                if (trigger instanceof CronTrigger) {                      CronTrigger cronTrigger = (CronTrigger) trigger;                      String cronExpression = cronTrigger.getCronExpression();                      map.put("jobTime",cronExpression);                }                  jobList.add(map);              }          } catch (SchedulerException e) {            e.printStackTrace();        }          return jobList;      }}

5、job类:

package com.yj.quartzjob;import java.text.SimpleDateFormat;import java.util.Date;import org.quartz.Job;import org.quartz.JobExecutionContext;import org.quartz.JobExecutionException;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;import com.yj.service.WeiXinService;/** * quart test * @author jing * */@Componentpublic class QuartzJob implements Job{    @Autowired    public WeiXinService service;    @Override    public void execute(JobExecutionContext arg0) throws JobExecutionException {        SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");        System.out.println("TestQuartJob 的运行 :"+dateFormat.format(new Date()));        service.getAccessToken();    }}

6、测试类:

@RequestMapping("add")    public void text(){        try {            String jobName="job1";            String jobGroupName="job1";            String jobTime="0/5 * * * * ? ";            SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");            System.out.println("TestQuartJob 开始启动:"+dateFormat.format(new Date()));            quartzManager.addJob(QuartzJob.class,jobName,jobGroupName,jobTime);        } catch (Exception e) {            e.printStackTrace();        }     }

7、maven引入:

            <!-- https://mvnrepository.com/artifact/org.quartz-scheduler/quartz -->            <dependency>                <groupId>org.quartz-scheduler</groupId>                <artifactId>quartz</artifactId>                <version>2.2.1</version>            </dependency>

8、监听器:

自定义一个监听类:

貌似Quartz的job在项目重启时,job都失效了,我是把每次启动的job都存放在数据库,然后项目启动时监听器读取数据库的job,然后添加job。

package com.yj.quartzjob;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import javax.servlet.ServletContextEvent;import javax.servlet.ServletContextListener;import org.quartz.Job;import org.springframework.web.context.support.WebApplicationContextUtils;import com.yj.until.QuartzManager;/** * 容器监听器 * @author jing */public class QuartzJobListener implements ServletContextListener {    public void contextInitialized(ServletContextEvent arg0) {        /***处理获取数据库的job表,然后遍历循环每个加到job中 ***/        QuartzManager quartzManager = WebApplicationContextUtils.getWebApplicationContext(arg0.getServletContext()).getBean(QuartzManager.class);        //此处就不写获取数据库了,模拟一个集合遍历的数据          List<Map<String,Object>> listMap=new ArrayList<>();        Map<String, Object> map1=new HashMap<String, Object>();        map1.put("jobClass","com.yj.quartzjob.QuartzJob");        map1.put("jobName","job1");        map1.put("jobGroupName","job1");        map1.put("jobTime","0/5 * * * * ? ");        listMap.add(map1);        for (Map<String, Object> map : listMap) {            try {                quartzManager.addJob((Class<? extends Job>)(Class.forName((String)map1.get("jobClass")).newInstance().getClass()),(String)map.get("jobName"), (String)map.get("jobGroupName"),(String)map.get("jobTime"));            } catch (Exception e) {                e.printStackTrace();            }         }        System.out.println("QuartzJobListener 启动了");    }    public void contextDestroyed(ServletContextEvent arg0) {    }}

web.xml的配置:

ps:自定义的监听类要在SpringMVC框架的监听器之后。

<listener>   <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener> <listener>   <listener-class>com.yj.quartzjob.QuartzJobListener</listener-class></listener>
阅读全文
1 0
原创粉丝点击