您的位置:首页 > 编程语言 > Java开发

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

2017-07-11 16:22 691 查看

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;
@Service
public 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());

d744
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
*
*/
@Component
public 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>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: