1.实现项目启动时在启动所有没有过期的任务
2.页面添加、修改、删除任务功能
3.页面功能包含设定任务的开始时间、结束时间、是否暂停功能(暂停功能的实现是直接删除任务,启用时在添加任务)
spring 5.0.5 quartz 2.3.0
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:task="http://www.springframework.org/schema/task"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="jobFactory" class="com.lx.dpis.risk.scheduler.JobFactory">bean>
<bean id="schedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="jobFactory" ref="jobFactory">property>
bean>
beans>
public class RiskOjectScheduler implements ApplicationListener<ContextRefreshedEvent> {
@Autowired
private RiskCheckTaskDao rctDao;
@Autowired
private QuartzManager qm;
public static final String DEFAULT_JOBGROUPNAME = "risk_jobGroupName";
public static final String DEFAULT_TRIGGERGROUPNAME = "risk_triggerGroupName";
// //@PostConstruct
// public void initJobs() {
// try {
// @SuppressWarnings("unchecked")
// List taskList = rctDao.findAll(null);
// for (RiskCheckTask rct : taskList) {
// qm.addJob(rct.getRcTaskId(), DEFAULT_JOBGROUPNAME, DEFAULT_TRIGGERNAME,
// DEFAULT_TRIGGERGROUPNAME,
// MyJob.class, rct.getCornExp(), rct.getRcTaskId());
// }
// } catch (Exception e) {
// e.printStackTrace();
// }
// }
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
if (event.getApplicationContext().getParent() == null) {
// root application context 没有parent,他就是老大.
// 需要执行的逻辑代码,当spring容器初始化完成后就会执行该方法。
List<RiskCheckTask> taskList = rctDao.findByProperty(new String[] { "executeFlag","status" }, new String[] { "1","1" });
if (taskList != null && taskList.size() > 0) {
for (RiskCheckTask rct : taskList) {
Date beginTime = null;
Date endTime = null;
String taskId = rct.getRcTaskId();
int checkStyle = Integer.valueOf(rct.getCheckCycle());
String checkStyleMode = rct.getCheckCycleMode();
int repeatHour = 0;
switch (checkStyleMode){
case "HOUR": repeatHour = checkStyle;break;
case "DAY":repeatHour = checkStyle*24;break;
case "MONTH":repeatHour = checkStyle*30*24;break;
case "WEEK":repeatHour = checkStyle*7*24;break;
}
try {
beginTime = DateTool.stringToDateByFormat(rct.getTaskBeginTime(), "yyyy-MM-dd HH:mm:ss");
endTime = DateTool.stringToDateByFormat(rct.getTaskEndTime(), "yyyy-MM-dd HH:mm:ss");
} catch (Exception e) {
e.printStackTrace();
}
//List riskInfoList = rctDao.getRiskTaskRel(taskId);
qm.addJobByInterval(rct.getRcTaskId(), DEFAULT_JOBGROUPNAME, rct.getRcTaskId(), DEFAULT_TRIGGERGROUPNAME,
RiskJob.class, taskId,repeatHour,beginTime,endTime);
}
}
}
}
}
@Component
public class QuartzManager {
@Autowired
private Scheduler scheduler;
/**
* 获取定时器调度实例
*
* @return 实例对象
*/
/*public static QuartzManager getInstance() {
if (null == instance) {
synchronized (QuartzManager.class) {
if (null == instance) {
instance = new QuartzManager();
}
}
}
return instance;
}*/
/**
* 功能: 添加一个定时任务
*
* @param jobName
* 任务名
* @param jobGroupName
* 任务组名
* @param triggerName
* 触发器名
* @param triggerGroupName
* 触发器组名
* @param jobClass
* 任务的类类型 eg:TimedMassJob.class
* @param cron
* 时间设置 表达式,参考quartz说明文档
*/
public void addJob(String jobName, String jobGroupName, String triggerName, String triggerGroupName,
Class<? extends Job> jobClass, String cron, Object... objects) {
try {
//cfb.set
// 任务名,任务组,任务执行类
JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName).build();
// 触发器
if (objects != null) {
for (int i = 0; i < objects.length; i++) {
jobDetail.getJobDataMap().put("data" + (i + 1), objects[i]);
}
}
TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();
// 触发器名,触发器组
triggerBuilder.withIdentity(triggerName, triggerGroupName);
triggerBuilder.startNow();
// 触发器时间设定
triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron));
// 创建Trigger对象
CronTrigger trigger = (CronTrigger) triggerBuilder.build();
// 调度容器设置JobDetail和Trigger
scheduler.scheduleJob(jobDetail, trigger);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 以時間間隔的方式添加任務
* @param jobName
* @param jobGroupName
* @param triggerName
* @param triggerGroupName
* @param jobClass
* @param objects
*/
public void addJobByInterval(String jobName, String jobGroupName, String triggerName, String triggerGroupName,
Class<? extends Job> jobClass, Object... objects) {
try {
// 任务名,任务组,任务执行类
JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName).build();
// 触发器
if (objects != null) {
for (int i = 0; i < objects.length; i++) {
jobDetail.getJobDataMap().put("data" + (i + 1), objects[i]);
}
}
TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();
// 触发器名,触发器组
triggerBuilder.withIdentity(triggerName, triggerGroupName);
triggerBuilder.startNow();
// 触发器时间设定
triggerBuilder.withSchedule(SimpleScheduleBuilder.repeatHourlyForever((int)objects[1]));
//triggerBuilder.withSchedule(SimpleScheduleBuilder.repeatSecondlyForever((int)objects[1]));
// 创建Trigger对象
SimpleTriggerImpl trigger = (SimpleTriggerImpl) triggerBuilder.build();
trigger.setStartTime((Date)objects[2]);
trigger.setEndTime((Date)objects[3]);
// 调度容器设置JobDetail和Trigger
scheduler.scheduleJob(jobDetail, trigger);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 功能:修改一个任务的触发时间
*
* @param jobName
* @param jobGroupName
* @param triggerName
* 触发器名
* @param triggerGroupName
* 触发器组名
* @param cron
* 时间设置,参考quartz说明文档
*/
public void modifyJobTimeByInterval(String jobName, String jobGroupName, String triggerName, String triggerGroupName,Object... objects) {
try {
int repeatHour=(int) objects[1];
Date beginTime = (Date) objects[2],endTime=(Date) objects[3];
TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName);
SimpleTriggerImpl trigger = (SimpleTriggerImpl) scheduler.getTrigger(triggerKey);
if (trigger == null) {
return;
}
long repeatMi = repeatHour*60*60*1000;
//long repeatMi = repeatHour*1000;
Date oldBeginTime = trigger.getStartTime();trigger.getStartTime();
Date oldEndTime = trigger.getEndTime();
long oldRepeatHour = trigger.getRepeatInterval();
if(repeatMi!=oldRepeatHour||!(beginTime.equals(oldBeginTime))||!(endTime.equals(oldEndTime))){
// 触发器
TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();
// 触发器名,触发器组
triggerBuilder.withIdentity(triggerName, triggerGroupName);
triggerBuilder.startNow();
// 触发器时间设定
//triggerBuilder.withSchedule(SimpleScheduleBuilder.repeatSecondlyForever((int)objects[1]));
triggerBuilder.withSchedule(SimpleScheduleBuilder.repeatHourlyForever((int) objects[1]));
// 创建Trigger对象
trigger = (SimpleTriggerImpl) triggerBuilder.build();
trigger.setStartTime((Date)objects[2]);
trigger.setEndTime((Date)objects[3]);
// 方式一 :修改一个任务的触发时间
scheduler.rescheduleJob(triggerKey, trigger);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public void modifyJobTime(String jobName, String jobGroupName, String triggerName, String triggerGroupName,String cron) {
try {
TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName);
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
if (trigger == null) {
return;
}
String oldTime = trigger.getCronExpression();
if (!oldTime.equalsIgnoreCase(cron)) {
// 触发器
TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();
// 触发器名,触发器组
triggerBuilder.withIdentity(triggerName, triggerGroupName);
triggerBuilder.startNow();
// 触发器时间设定
triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron));
// 创建Trigger对象
trigger = (CronTrigger) triggerBuilder.build();
// 方式一 :修改一个任务的触发时间
scheduler.rescheduleJob(triggerKey, trigger);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 功能: 移除一个任务
*
* @param jobName
* @param jobGroupName
* @param triggerName
* @param triggerGroupName
*/
public void removeJob(String jobName, String jobGroupName, String triggerName, String triggerGroupName) {
try {
TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName);
// 停止触发器
scheduler.pauseTrigger(triggerKey);
// 移除触发器
scheduler.unscheduleJob(triggerKey);
// 删除任务
scheduler.deleteJob(JobKey.jobKey(jobName, jobGroupName));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* @Description:暂停一个任务
* @param jobName
* @param jobGroupName
*/
public void pauseJob(String jobName, String jobGroupName) {
JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);
try {
scheduler.pauseJob(jobKey);
} catch (SchedulerException e) {
e.printStackTrace();
}
}
/**
* @Description:恢复一个任务
* @param jobName
* @param jobGroupName
* @date 2018年5月17日 上午9:56:09
*/
public void resumeJob(String jobName, String jobGroupName) {
JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);
try {
scheduler.resumeJob(jobKey);
} catch (SchedulerException e) {
e.printStackTrace();
}
}
/**
*
* 功能:启动所有定时任务
*/
public void startJobs() {
try {
if (scheduler.isStarted()) {
System.out.println("定时器已启动。");
} else {
scheduler.start();
}
} catch (SchedulerException e1) {
e1.printStackTrace();
}
}
/**
* 功能:关闭所有定时任务
*/
public void shutdownJobs() {
try {
if (!scheduler.isShutdown()) {
scheduler.shutdown();
}
} catch (SchedulerException e) {
e.printStackTrace();
}
}
public static List<String> getRecentTriggerTime(String cron) {
List<String> list = new ArrayList<String>();
try {
CronTriggerImpl cronTriggerImpl = new CronTriggerImpl();
cronTriggerImpl.setCronExpression(cron);
// 这个是重点,一行代码搞定
List<Date> dates = TriggerUtils.computeFireTimes(cronTriggerImpl, null, 8);
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
for (Date date : dates) {
list.add(dateFormat.format(date));
}
} catch (ParseException e) {
e.printStackTrace();
}
return list;
}
}
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.applicationContext-quartz.xml
<beans>
<bean name="quartzScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="applicationContextSchedulerContextKey" value="applicationContextKey"/>
<property name="configLocation" value="classpath:quartz.properties"/>
bean>
beans>
2.对应的job任务获取ApplicationContext
public class QuartzJobBean implements Job {
/* (non-Javadoc)
* @see org.quartz.Job#execute(org.quartz.JobExecutionContext)
*/
@Override
public void execute(JobExecutionContext jobContext) throws JobExecutionException {
String jobId = jobContext.getJobDetail().getDescription();
String serviceId = jobContext.getTrigger().getDescription();
ApplicationContext applicationContext=null;
try {
applicationContext=getApplicationContext(jobContext);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
WebServiceService webServiceService = (WebServiceService) applicationContext.getBean("webServiceService");
WebServicePOJO webService = webServiceService.getWebService(serviceId);
ScheduleService.schedule(webService.getNameSpace(), webService.getServiceName(), webService.getWsdlURL(), webService.getMethod());
}
private static final String APPLICATION_CONTEXT_KEY = "applicationContextKey";
private ApplicationContext getApplicationContext(JobExecutionContext context) throws Exception {
ApplicationContext appCtx = null;
appCtx = (ApplicationContext) context.getScheduler().getContext().get(APPLICATION_CONTEXT_KEY);
if (appCtx == null) {
throw new JobExecutionException("No application context available in scheduler context for key \"" + APPLICATION_CONTEXT_KEY + "\"");
}
return appCtx;
}
}
详细查看https://www.tuicool.com/articles/jyuEbi
//在定时任务里面获取sessionFactory,然后OpenSession,执行完成后关闭:
WebApplicationContext wac = ContextLoader.getCurrentWebApplicationContext();
SessionFactory factory=wac.getBean(SessionFactory.class);
Session session=factory.openSession();
Query query = session.createQuery("from User");
List<User> userlist=query.list();
session.close();
public class RiskJob implements Job {
@Autowired
private SessionFactory sf;//此处使用@Autowired注入需要用到配置文件JobFactory类
public static final String DEFAULT_JOBGROUPNAME = "risk_jobGroupName";
public static final String DEFAULT_TRIGGERGROUPNAME = "risk_triggerGroupName";
//Job实现类 此处需要使用openSession,使用getCurrentSession会报错Could not obtain transaction-synchronized Session for current thread
//原因是因为从定时任务调用时会启动一个新的线程,而Hibernate和Spring集成Session是绑定到thread上面的。
public Session getSession() {
return sf.openSession();
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
System.err.println("任務運行開始-------- start --------");
Session session = this.getSession();
try {
String taskId = (String) context.getJobDetail().getJobDataMap().get("data1");
Date scheduledFireTime = context.getScheduledFireTime();
Date nextFireTime = context.getNextFireTime();
StringBuffer sql = new StringBuffer(
"SELECT rct.rc_task_id AS rcTaskId, rct.RC_TASK_NAME AS rcTaskName, rct.EXECUTOR_NO AS executorNo, rct.EXECUTOR AS executor, rct.cronExp, rct.TASK_BEGIN_TIME AS taskBeginTime, rct.TASK_END_TIME AS taskEndTime, rto.RISK_OBJECT_ID AS riskObjectId FROM dp_risk_check_task rct, dp_rc_task_obj_rel rto, dp_risk_object ro WHERE rct.RC_TASK_ID = rto.RC_TASK_ID AND rto.RISK_OBJECT_ID = ro.id AND ro.ISVALID='1' AND ro.STATUS='1' AND rct.STATUS = '1' AND rto.STATUS = '1' ");
if (StringUtils.isNotEmpty(taskId)) {
sql.append(" and rct.rc_task_id ='" + taskId + "'");
}
Query s = session.createSQLQuery(sql.toString());
s.setResultTransformer(Transformers.aliasToBean(RiskInfo.class));
List<RiskInfo> list = s.list();
if(list!=null&&list.size()>0){
for (RiskInfo ri : list) {
RiskCheckRecord rr = new RiskCheckRecord();
rr.setRcRecordId(UUIDUtil.uuid());
rr.setRcTaskId(ri.getRcTaskId());
rr.setRiskObjectId(ri.getRiskObjectId());
rr.setExecutorNo(ri.getExecutorNo());
rr.setExecutor(ri.getExecutor());
rr.setBeginTime(DateTool.dateToString(scheduledFireTime, "yyyy-MM-dd HH:mm:ss"));
rr.setEndTime(DateTool.dateToString(nextFireTime, "yyyy-MM-dd HH:mm:ss"));
rr.setCheckStatus("0");
rr.setStatus("1");
rr.setCreatorNo("sys");
rr.setCreator("管理員");
rr.setCreateDate(new Date());
session.save(rr);
session.beginTransaction().commit();
}
}
//String jobName = context.getJobDetail().getKey().getName();
//String jobGroup = context.getJobDetail().getKey().getGroup();
// String triggerName = context.getTrigger().getKey().getName();
// String triggerGroup = context.getTrigger().getKey().getGroup();
/*SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH時mm分ss秒");
System.out.println("任務Key:" + jobName + ".." + jobGroup + " 正在執行,執行時間: "
+ dateFormat.format(Calendar.getInstance().getTime()));*/
} catch (Exception e) {
System.out.println("捕獲異常===" + e);
e.printStackTrace();
} finally {
session.close();
}
System.err.println("任務運行結束-------- end --------");
}
}
//添加任務
if(StringUtils.equals("1", rct.getExecuteFlag())){
qm.addJobByInterval(rcTaskId, DEFAULT_JOBGROUPNAME, rcTaskId, DEFAULT_TRIGGERGROUPNAME,
RiskJob.class,rcTaskId,repeatHour,beginTime,endTime);
}
if(StringUtils.equals(exectueFlagBefore, "1")&&StringUtils.equals(exectueFlagAfter, "0")){
qm.removeJob(rct.getRcTaskId(), DEFAULT_JOBGROUPNAME, rct.getRcTaskId(), DEFAULT_TRIGGERGROUPNAME);
}else if(StringUtils.equals(exectueFlagBefore, "0")&&StringUtils.equals(exectueFlagAfter, "1")){
qm.addJobByInterval(rct.getRcTaskId(), DEFAULT_JOBGROUPNAME, rct.getRcTaskId(), DEFAULT_TRIGGERGROUPNAME,
RiskJob.class, rct.getRcTaskId(),repeatHour,beginTime,endTime);
}else if(StringUtils.equals(exectueFlagBefore, exectueFlagAfter)&&StringUtils.equals(exectueFlagBefore, "1")){
qm.modifyJobTimeByInterval(rct.getRcTaskId(), DEFAULT_JOBGROUPNAME, rct.getRcTaskId(), DEFAULT_TRIGGERGROUPNAME, rct.getRcTaskId(),repeatHour,beginTime,endTime);
}
添加修改任务后每个任务都会调用Job实现类的execute方法
该教程实现本人项目的功能