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

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

}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

3、Spring.XML的配置:





1
2
3
4
5

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

}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247

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

}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14

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>

1
2
3
4
5
6

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) {
}

}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

web.xml的配置:

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


org.springframework.web.context.ContextLoaderListener


com.yj.quartzjob.QuartzJobListener

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值