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

Quartz任务调度[Spring+Quartz结合]_实现任务的动态添加、修改和删除

2017-05-15 16:43 666 查看
原文地址:http://blog.csdn.net/yangrunkangbla/article/details/51473169

版权声明:本文为博主原创文章,未经博主允许不得转载。

Git地址:https://git.oschina.net/Bla/Quartz.git
项目框架图



下面开始贴代码了,不过先贴数据库^^
-- Create table Oracle数据库
create table QUARTZ_SCHEDULEJOB
(
id              VARCHAR2(32),
job_name        VARCHAR2(32) not null,
job_status      NVARCHAR2(3) default 0 not null,
cron_expression NVARCHAR2(32) not null,
concurrent      NVARCHAR2(3) default 0,
description     NVARCHAR2(320),
job_group       NVARCHAR2(32),
target_object   NVARCHAR2(32),
target_method   NVARCHAR2(32),
is_spring_bean  NVARCHAR2(3),
clazz           NVARCHAR2(80),
child_jobs      NVARCHAR2(302)
)
tablespace USERS
pctfree 10
initrans 1
maxtrans 255
storage
(
initial 64K
next 1M
minextents 1
maxextents unlimited
);
-- Add comments to the columns
comment on column QUARTZ_SCHEDULEJOB.id
is '任务id';
comment on column QUARTZ_SCHEDULEJOB.job_name
is '任务名称';
comment on column QUARTZ_SCHEDULEJOB.job_status
is '任务状态 0禁用 1启用';
comment on column QUARTZ_SCHEDULEJOB.cron_expression
is '任务运行时间表达式';
comment on column QUARTZ_SCHEDULEJOB.concurrent
is '是否并发启动任务 0禁用 1启用';
comment on column QUARTZ_SCHEDULEJOB.description
is '任务描述';
comment on column QUARTZ_SCHEDULEJOB.job_group
is '任务所属组';
comment on column QUARTZ_SCHEDULEJOB.target_object
is '执行任务的类';
comment on column QUARTZ_SCHEDULEJOB.target_method
is '任务类中的方法';
comment on column QUARTZ_SCHEDULEJOB.is_spring_bean
is '是否是Spring中定义的Bean 0不是 1是 如果是0需要设置全类名,测试CLAZZ字段需要配置';
comment on column QUARTZ_SCHEDULEJOB.clazz
is '如果不是Spring中的Bean需要配置全类名用于反射';
comment on column QUARTZ_SCHEDULEJOB.child_jobs
is '[一系列(包括单个)]的子任务(按照配置的顺序执行)';
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
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
好,开始正式贴代码….之前…先贴数据库数据
insert into QUARTZ_SCHEDULEJOB (id, job_name, job_status, cron_expression, concurrent, description, job_group, target_object, target_method, is_spring_bean, clazz, child_jobs)
values ('01', 'car_starting', '0', '0/5 * * * * ?', '0', '车辆启动', 'car', 'car', 'starting', '1', null, '03,02');
insert into QUARTZ_SCHEDULEJOB (id, job_name, job_status, cron_expression, concurrent, description, job_group, target_object, target_method, is_spring_bean, clazz, child_jobs)
values ('02', 'car_running', '1', '0/30 * * * * ?', '0', '车辆开动', 'car', 'car', 'running', '1', null, '06,05');
insert into QUARTZ_SCHEDULEJOB (id, job_name, job_status, cron_expression, concurrent, description, job_group, target_object, target_method, is_spring_bean, clazz, child_jobs)
values ('03', 'car_stop', '0', '0/3 * * * * ?', '0', '车辆停止', 'car', 'car', 'stop', '1', null, null);
insert into QUARTZ_SCHEDULEJOB (id, job_name, job_status, cron_expression, concurrent, description, job_group, target_object, target_method, is_spring_bean, clazz, child_jobs)
values ('04', 'people_birth', '0', '0/6 * * * * ?', '0', '人出生', 'people', 'people', 'birth', '1', null, '01');
insert into QUARTZ_SCHEDULEJOB (id, job_name, job_status, cron_expression, concurrent, description, job_group, target_object, target_method, is_spring_bean, clazz, child_jobs)
values ('05', 'people_life', '0', '0/3 * * * * ?', '0', '人生活', 'people', 'people', 'life', '1', null, null);
insert into QUARTZ_SCHEDULEJOB (id, job_name, job_status, cron_expression, concurrent, description, job_group, target_object, target_method, is_spring_bean, clazz, child_jobs)
values ('06', 'people_death', '0', '0/4 * * * * ?', '0', '人死亡', 'people', 'people', 'death', '1', null, null);
insert into QUARTZ_SCHEDULEJOB (id, job_name, job_status, cron_expression, concurrent, description, job_group, target_object, target_method, is_spring_bean, clazz, child_jobs)
values ('07', 'out', '0', '0/4 * * * * ?', '0', 'outout', 'outout', 'testreflectionClazz', 'testreflectionClazz', '0', 'com.cn.model.TestreflectionClazz', null);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
1
2
3
4
5
6
7
8
9
10
11
12
13
14
好,这次真的来了

-com.cn.model.ScheduleJob
package com.cn.model;

import java.io.Serializable;

/**
* 计划任务信息
* @author 杨润康
*/
public class ScheduleJob implements Serializable{

private static final long serialVersionUID = -6268330198581041868L;

/** 任务ID */
private String jobId;
/** 任务名称 */
private String jobName;
/** 任务分组 */
private String jobGroup;
/** 任务状态 0禁用 1启用 2删除*/
private String jobStatus;
/** 任务运行时间表达式 */
private String cronExpression;
/** 任务描述 */
private String description;
/** 任务类 */
private String targetObject;
/** 任务方法 */
private String targetMethod;
/** 是否是Spring中定义的Bean */
private String isSpringBean;
/** 如果isSpringBean = 0需要设置全类名,测试CLAZZ字段需要配置 */
private String clazz;
/** 是否并发 0禁用 1启用 */
private String concurrent;
/** 一系列的子任务,逗号分开,表示该任务执行完,之后需要执行的任务 */
private String childJobs;

//getter setter方法省略
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
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
- com.cn.model.TestreflectionClazz

package com.cn.model;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.log4j.Logger;

/**
* 测试不是Spring中的Bean  测试isSpringBean为0 的情况
* @author 杨润康
* 测试OK
*/
public class TestreflectionClazz {

private Logger logger = Logger.getLogger(TestreflectionClazz.class);

private DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

public void testreflectionClazz(){
logger.info(df.format(new Date()) + "------------>TestreflectionClazz");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

public void task1_test1_test2(){

}

}
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
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
- com.cn.quartz.inputs.QuartzJobFactory

package com.cn.quartz.inputs;

import java.util.List;

import org.apache.log4j.Logger;
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean;

import com.cn.model.ScheduleJob;
import com.cn.util.DBUtil;
import com.cn.util.QuartzUtil;
import com.cn.util.SpringContextUtil;

/**
* 定时任务运行工厂类 【核心类】
*
* @author 杨润康
*/
@DisallowConcurrentExecution
public class QuartzJobFactory {// 实现的是无状态的Job

private Logger logger = Logger.getLogger(QuartzJobFactory.class);

/**
* @Note : 扫面数据库,查看是否有计划任务的变动
*/
public void arrageScheduleJob() {
try {

List<ScheduleJob> jobList = DBUtil.getScheduleJobs();
if (jobList.size() != 0) {
for (ScheduleJob job : jobList) {
// Keys are composed of both a name and group, and the name  must be unique within the group
TriggerKey triggerKey = TriggerKey.triggerKey(job.getJobName(), job.getJobGroup());
// 获取trigger
CronTrigger trigger = (CronTrigger) QuartzUtil.scheduler.getTrigger(triggerKey);
// 不存在,创建一个
if (null == trigger) {
createSheduler(QuartzUtil.scheduler, job);
} else {// Trigger已存在,那么更新相应的定时设置
updateScheduler(QuartzUtil.scheduler, job, triggerKey, trigger);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}

/**
* 更新相应的定时设置 根据job_status做相应的处理
*
* @param scheduler
* @param job
* @param triggerKey
* @param trigger
* @throws SchedulerException
*/
private void updateScheduler(Scheduler scheduler, ScheduleJob job, TriggerKey triggerKey, CronTrigger trigger)
throws SchedulerException {
if (job.getJobStatus().equals("1")) {// 0禁用 1启用
if (!trigger.getCronExpression().equalsIgnoreCase(job.getCronExpression())) {
// 表达式调度构建器
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());
// 按新的cronExpression表达式重新构建trigger
trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
// 按新的trigger重新设置job执行
scheduler.rescheduleJob(triggerKey, trigger);
logger.info(job.getJobGroup() + "." + job.getJobName() + " 更新完毕,目前cron表达式为:" + job.getCronExpression()
+ " isSpringBean:" + job.getIsSpringBean() + " concurrent: " + job.getConcurrent());
}
} else if (job.getJobStatus().equals("0")) {
scheduler.pauseTrigger(triggerKey);// 停止触发器
scheduler.unscheduleJob(triggerKey);// 移除触发器
scheduler.deleteJob(trigger.getJobKey());// 删除任务
logger.info(job.getJobGroup() + "." + job.getJobName() + "删除完毕");
}

}

/**
* 创建一个定时任务,并做安排
*
* @param scheduler
* @param job
* @throws SchedulerException
* @throws Exception
*/
public void createSheduler(Scheduler scheduler, ScheduleJob job) throws Exception {
// 在工作状态可用时,即job_status = 1 ,开始创建
if (job.getJobStatus().equals("1")) {
// 新建一个基于Spring的管理Job类
MethodInvokingJobDetailFactoryBean methodInvJobDetailFB = new MethodInvokingJobDetailFactoryBean();
// 设置Job名称
methodInvJobDetailFB.setName(job.getJobName());
// 定义的任务类为Spring的定义的Bean则调用 getBean方法
if (job.getIsSpringBean().equals("1")) {// 是Spring中定义的Bean
methodInvJobDetailFB
.setTargetObject(SpringContextUtil.getApplicationContext().getBean(job.getTargetObject()));
} else {// 不是
methodInvJobDetailFB.setTargetObject(Class.forName(job.getClazz()).newInstance());
}
// 设置任务方法
methodInvJobDetailFB.setTargetMethod(job.getTargetMethod());
// 将管理Job类提交到计划管理类
methodInvJobDetailFB.afterPropertiesSet();
/** 并发设置 */
methodInvJobDetailFB.setConcurrent(job.getConcurrent().equals("1") ? true : false);

JobDetail jobDetail = methodInvJobDetailFB.getObject();// 动态
jobDetail.getJobDataMap().put("scheduleJob", job);
//jobName存入到队列 每隔一段时间就会扫描所以需要时检测
if(!QuartzUtil.jobNames.contains(job.getJobName())){
QuartzUtil.jobNames.add(job.getJobName());
}

// 表达式调度构建器
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());
// 按新的cronExpression表达式构建一个新的trigger
CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(job.getJobName(), job.getJobGroup())
.withSchedule(scheduleBuilder).build();

scheduler.scheduleJob(jobDetail, trigger);// 注入到管理类
logger.info(job.getJobGroup() + "." + job.getJobName() + "创建完毕");
}
}

}
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
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
- com.cn.tasks.Car

package com.cn.tasks;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;

import com.cn.util.QuartzUtil;

@Component
public class Car {

private Logger logger = Logger.getLogger(Car.class);
private DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

public void starting() {
logger.info(df.format(new Date()) + "---------->车辆启动");

String mainJob = QuartzUtil.getScheduleJobName("car_starting");
QuartzUtil.executeChildJobs(mainJob);
}

public void running() {
logger.info(df.format(new Date()) + "---------->车辆开动");

String mainJob = QuartzUtil.getScheduleJobName("car_running");
QuartzUtil.executeChildJobs(mainJob);
}

public void stop() {
logger.info(df.format(new Date()) + "---------->车辆停止");

String mainJob = QuartzUtil.getScheduleJobName("car_stop");
QuartzUtil.executeChildJobs(mainJob);
}
}
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
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
- com.cn.tasks.People

package com.cn.tasks;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;

import com.cn.util.QuartzUtil;
import com.cn.util.Util;

@Component
public class People {

private Logger logger = Logger.getLogger(Car.class);
private DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

public synchronized void birth(){
//      logger.info("人出生耗时操作10s");
//      Util.time_10s();
logger.info(df.format(new Date()) + "---------->人出生");
String mainJob = QuartzUtil.getScheduleJobName("people_birth");
QuartzUtil.executeChildJobs(mainJob);
}

public synchronized void life(){
//      logger.info("人生活耗时操作8s");
//      Util.time_8s();
logger.info(df.format(new Date()) + "---------->人生活");
String mainJob = QuartzUtil.getScheduleJobName("people_life");
QuartzUtil.executeChildJobs(mainJob);
}

public synchronized void death(){
//      logger.info("人死亡耗时操作6s");
//      Util.time_6s();
logger.info(df.format(new Date()) + "---------->人死亡");
String mainJob = QuartzUtil.getScheduleJobName("people_death");
QuartzUtil.executeChildJobs(mainJob);
}

}
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
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
- com.cn.util.DBUtil

package com.cn.util;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import com.cn.model.ScheduleJob;

/**
* 数据库工具类 【测试时用,正式用MyBatis】
*
* @author 杨润康Bla
*
*/
public class DBUtil {
/**
* 查询数据库任务设置,返回列表
*
* @return 数据库任务设置列表
*/
public static List<ScheduleJob> getScheduleJobs() {
List<ScheduleJob> result = new ArrayList<ScheduleJob>();
Connection con = null;
Statement smt = null;
ResultSet rs = null;

con = new DBUtil().getDBConnection();
try {
if (con != null) {
smt = con.createStatement();
con.setAutoCommit(false);
String sql = "SELECT ID,JOB_NAME,JOB_STATUS,CRON_EXPRESSION,CONCURRENT,DESCRIPTION,JOB_GROUP,TARGET_OBJECT,TARGET_METHOD,IS_SPRING_BEAN,CLAZZ,CHILD_JOBS FROM QUARTZ_SCHEDULEJOB";
rs = smt.executeQuery(sql);
while (rs.next()) {
ScheduleJob sj = new ScheduleJob();
sj.setJobId(rs.getString("ID"));
sj.setJobName(rs.getString("JOB_NAME"));
sj.setJobGroup(rs.getString("JOB_GROUP"));
sj.setJobStatus(rs.getString("JOB_STATUS"));
sj.setCronExpression(rs.getString("CRON_EXPRESSION"));
sj.setDescription(rs.getString("DESCRIPTION"));
sj.setTargetMethod(rs.getString("TARGET_METHOD"));
sj.setTargetObject(rs.getString("TARGET_OBJECT"));
sj.setIsSpringBean(rs.getString("IS_SPRING_BEAN"));
sj.setClazz(rs.getString("CLAZZ"));
sj.setConcurrent(rs.getString("CONCURRENT"));
sj.setChildJobs(rs.getString("CHILD_JOBS"));

result.add(sj);
}
rs.close();
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return result;
}

public static ScheduleJob getScheduleJobById(String id) {
Connection con = null;
Statement smt = null;
ResultSet rs = null;
ScheduleJob sj = null;
con = new DBUtil().getDBConnection();
try {
if (con != null) {
smt = con.createStatement();
con.setAutoCommit(false);
String sql = "SELECT "
+ "ID,JOB_NAME,JOB_STATUS,CRON_EXPRESSION,CONCURRENT,DESCRIPTION,JOB_GROUP,"
+ "TARGET_OBJECT,TARGET_METHOD,IS_SPRING_BEAN,CLAZZ,CHILD_JOBS "
+ "FROM QUARTZ_SCHEDULEJOB WHERE ID = '"+id+"'";
rs = smt.executeQuery(sql);
while (rs.next()) {
sj = new ScheduleJob();
sj.setJobId(rs.getString("ID"));
sj.setJobName(rs.getString("JOB_NAME"));
sj.setJobGroup(rs.getString("JOB_GROUP"));
sj.setJobStatus(rs.getString("JOB_STATUS"));
sj.setCronExpression(null);//子任务不要
//                  sj.setCronExpression(rs.getString("CRON_EXPRESSION"));
sj.setDescription(rs.getString("DESCRIPTION"));
sj.setTargetMethod(rs.getString("TARGET_METHOD"));
sj.setTargetObject(rs.getString("TARGET_OBJECT"));
sj.setIsSpringBean(rs.getString("IS_SPRING_BEAN"));
sj.setClazz(rs.getString("CLAZZ"));
sj.setConcurrent(rs.getString("CONCURRENT"));
sj.setChildJobs(rs.getString("CHILD_JOBS"));
}
rs.close();
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return sj;
}

/**
* 根据主工作名称获取子工作
* @param mainJob
*/
public static String getChildsJobByMainJobName(String mainJob) {
Connection con = null;
Statement smt = null;
ResultSet rs = null;
con = new DBUtil().getDBConnection();
String result = "";
try {
if (con != null) {
smt = con.createStatement();
con.setAutoCommit(false);
//因为只是主任务需要cron子任务不需要,所以只需要查找childs_jobs
String sql = "SELECT CHILD_JOBS FROM QUARTZ_SCHEDULEJOB WHERE JOB_NAME = '"+mainJob+"'";
rs = smt.executeQuery(sql);
if(rs.next()){
result = rs.getString(1);
}
rs.close();
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return result;
}

public Connection getDBConnection() {
Connection conn = null;
String driver = "";
String url = "";
String user = "";
String password = "";
Properties props = new Properties();
try {
props.load(this.getClass().getClassLoader().getResourceAsStream("default.properties"));
driver = props.getProperty("jdbc.driver");
url = props.getProperty("jdbc.url");
user = props.getProperty("jdbc.username");
password = props.getProperty("jdbc.password");

Class.forName(driver);
conn = DriverManager.getConnection(url, user, password);

return conn;
} catch (Exception e) {
e.printStackTrace();
}

return null;
}
}
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
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
- com.cn.util.QuartzUtil

package com.cn.util;

import java.util.ArrayList;
import java.util.List;

import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdScheduler;
import org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean;

import com.cn.model.ScheduleJob;

/**
* Quartz工具类
*
* @author 杨润康Bla
*
*/
public class QuartzUtil {

//  private static Logger logger = Logger.getLogger(QuartzUtil.class);

// 主工作需要保持名称唯一
public static List<String> jobNames = new ArrayList<String>();

// 公用Scheduler
public static Scheduler scheduler = (StdScheduler) SpringContextUtil.getApplicationContext()
.getBean("schedulerFactoryBean"); // 同一个对象
// 循环队列取出目标工作对象

public static String getScheduleJobName(String jobName) {
if (jobNames.contains(jobName)) { // 如果队列中有id,说明其子任务需要执行
return jobName;
}
return null;
}

/**
* 创建子任务
* @param job
* @throws Exception
*/
public static void createChildJob(ScheduleJob job) throws Exception {
job.setJobName(UUIDGenerator.getUUID()+job.getJobName()); //只是当前任务的名字而已,暂时的标记作用,不影响配置
MethodInvokingJobDetailFactoryBean methodInvJobDetailFB = new MethodInvokingJobDetailFactoryBean();
// 设置Job组名称
methodInvJobDetailFB.setGroup(job.getJobGroup());
// 设置Job名称
methodInvJobDetailFB.setName(job.getJobName()); // 注意设置的顺序,如果在管理Job类提交到计划管理类之后设置就会设置不上
// 定义的任务类为Spring的定义的Bean则调用 getBean方法
if (job.getIsSpringBean().equals("1")) {// 是Spring中定义的Bean
methodInvJobDetailFB
.setTargetObject(SpringContextUtil.getApplicationContext().getBean(job.getTargetObject()));
} else {// 不是就直接new
methodInvJobDetailFB.setTargetObject(Class.forName(job.getClazz()).newInstance());
}
// 设置任务方法
methodInvJobDetailFB.setTargetMethod(job.getTargetMethod());
// 将管理Job类提交到计划管理类
methodInvJobDetailFB.afterPropertiesSet();

/** 并发设置 */
methodInvJobDetailFB.setConcurrent(job.getConcurrent().equals("1") ? true : false);

JobDetail jobDetail = (JobDetail) methodInvJobDetailFB.getObject();// 动态
jobDetail.getJobDataMap().put("scheduleJob", job);

// 不按照表达式
Trigger trigger = TriggerBuilder.newTrigger()
// 保证键值不一样
.withIdentity(job.getJobName(), job.getJobGroup())
//              .usingJobData("","")//可以存储数据
.build();
/**
原理:
因为是立即执行,没有用到表达式嘛,所以按照实际的调度创建顺序依次执行
*/
QuartzUtil.scheduler.standby(); //暂时停止 任务都安排完之后统一启动 解决耗时任务按照顺序部署后执行紊乱的问题
QuartzUtil.scheduler.scheduleJob(jobDetail, trigger);// 注入到管理类
//      logger.info("子:" + job.getJobGroup() + "." + job.getJobName() + "创建完毕");
}

/**
* 执行子任务
* @param mainJob
* @throws Exception
* @throws Exception
*/
public static void executeChildJobs(String mainJob) {
if(mainJob!=null){
String childs = DBUtil.getChildsJobByMainJobName(mainJob);
if(null != childs){ //有子任务时才执行
String[] childsJobId = DBUtil.getChildsJobByMainJobName(mainJob).split(",");
for(String childJobId : childsJobId){
//                  System.out.println(childJobId); 打印当前任务的子任务
if(!"".equals(childJobId)){
ScheduleJob job = DBUtil.getScheduleJobById(childJobId);
try {
QuartzUtil.createChildJob(job);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
try {
QuartzUtil.scheduler.start();//任务安排完之后启动 解决耗时任务按照顺序部署后执行紊乱的问题
} catch (SchedulerException e) {
e.printStackTrace();
}
}
}
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
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
- com.cn.util.SpringContextUtil

package com.cn.util;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

/**
* Spring上下文工具
* @author 杨润康Bla
*  */
public class SpringContextUtil implements ApplicationContextAware {
// Spring应用上下文环境
private static ApplicationContext applicationContext;
/**
* 实现ApplicationContextAware接口的回调方法,设置上下文环境
*
* @param applicationContext
*/
public void setApplicationContext(ApplicationContext applicationContext) {
SpringContextUtil.applicationContext = applicationContext;
}
/**
* @return ApplicationContext
*/
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
/**
* 获取对象
*
* @param name
* @return Object
* @throws BeansException
*/
public static Object getBean(String name) throws BeansException {
return applicationContext.getBean(name);
}
}
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
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
- com.cn.util.Util

package com.cn.util;

/**
* 工具
* @author 杨润康
*
*/
public class Util {
public static void time_6s(){
try {
Thread.sleep(6*1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void time_10s(){
try {
Thread.sleep(10*1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void time_8s(){
try {
Thread.sleep(8*1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
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
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
com.cn.util.UUIDGenerator
package com.cn.util;

import java.util.UUID;

public class UUIDGenerator {
public static String getUUID(){
String s = UUID.randomUUID().toString();
return s.substring(0, 8) + s.substring(9, 13) + s.substring(14, 18) + s.substring(19, 23) + s.substring(24);
}
}
1
2
3
4
5
6
7
8
9
10
11
1
2
3
4
5
6
7
8
9
10
11
applicationContext-quartz.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util"
xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:c="http://www.springframework.org/schema/c" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.0.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring-1.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> 
<!-- ==========动态添加任务START========== -->
<!-- 注入StdSchedulerFactory 注入这个类可以使用quartz.properties配置文件 -->
<bean id="stdSchedulerFactory" class="org.quartz.impl.StdSchedulerFactory" />

<!-- 注册SpringContextUtil用于获取ApplicationContext -->
<bean id="springContextUtil" class="com.cn.util.SpringContextUtil"></bean>

<!-- 注册QuartzJobFactory -->
<bean id="quartzJobFactory" class="com.cn.quartz.inputs.QuartzJobFactory" />

<!-- 主定时计划 -->
<bean id="managerTriggerBean"
class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
<property name="jobDetail" ref="methodInvokingJobDetailFactoryBean" />
<!-- 延迟启动 -->
<property name="startDelay" value="1000"></property>
<property name="repeatInterval" value="6000"></property>
</bean>

<!-- 注册SchedulerFactoryBean -->
<bean id="schedulerFactoryBean"
class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="managerTriggerBean" />
</list>
</property>
</bean>

<!-- jobDetail -->
<bean id="methodInvokingJobDetailFactoryBean" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="quartzJobFactory" />
<property name="targetMethod" value="arrageScheduleJob" />
</bean>

<!-- ==========动态添加任务END========== -->
<!-- 扫表任务包 -->
<context:component-scan base-package="com.cn.tasks"></context:component-scan>

</beans>
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
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
default.properties
jdbc.validate=SELECT 1 FROM DUAL
jdbc.driver=oracle.jdbc.OracleDriver
jdbc.url=jdbc:oracle:thin:@localhost:1521:orcl
jdbc.username=quartz
jdbc.password=quartz
SERVER_HOME=D:/javaTool/luna/ws/.metadata/.plugins/org.eclipse.wst.server.core/tmp0
1
2
3
4
5
6
1
2
3
4
5
6
log4j.properties
省略,因为没有意义,网上也很多,复制过来就行
1
1
quartz.properties
##集群配置
org.quartz.scheduler.instanceName: DefaultQuartzScheduler
org.quartz.scheduler.rmi.export: false
org.quartz.scheduler.rmi.proxy: false
org.quartz.scheduler.wrapJobExecutionInUserTransaction: false
#
org.quartz.threadPool.class: org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount: 10
org.quartz.threadPool.threadPriority: 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread: true
org.quartz.jobStore.misfireThreshold: 60000
#
##默认配置,数据保存到内存
org.quartz.jobStore.class: org.quartz.simpl.RAMJobStore
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>Spring_Quartz_Mybatis</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>

<servlet>
<servlet-name>springDispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext-quartz.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>springDispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

顶1踩1
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数据库 quartz 并发
相关文章推荐