Spring整合Quartz实现动态定时任务
2016-01-27 14:10
846 查看
</pre><p>1.创建动态定时任务实体</p><p><pre name="code" class="java">import java.util.Date; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.SequenceGenerator; import javax.persistence.Table; /** * 动态定时任务 * * @author * */ @Entity @Table(name = "SCHEDULE_JOB", schema = "JLW") public class ScheduleJob implements java.io.Serializable { private static final long serialVersionUID = 7058240968903003001L; private Integer id; private Date createTime; private Date updateTime; private String jobName;// 任务名称 private String jobGroup;// 任务分组 private String jobStatus;// 任务状态 是否启动任务 private String cronExpression;// cron表达式 private String description;// 描述 private String beanClass;// 任务执行时调用哪个类的方法 包名+类名 private String isConcurrent;// 任务是否有状态(是否并发任务) private String springId;// spring bean private String methodName;// 任务调用的方法名 @SequenceGenerator(name = "generator", sequenceName = "SEQ_SCHEDULE_JOB") @Id @GeneratedValue(strategy = GenerationType.AUTO, generator = "generator") @Column(name = "ID", unique = true, nullable = false, precision = 10, scale = 0) public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } @Column(name = "CREATETIME") public Date getCreateTime() { return createTime; } public void setCreateTime(Date createTime) { this.createTime = createTime; } @Column(name = "UPDATETIME") public Date getUpdateTime() { return updateTime; } public void setUpdateTime(Date updateTime) { this.updateTime = updateTime; } @Column(name = "JOBNAME") public String getJobName() { return jobName; } public void setJobName(String jobName) { this.jobName = jobName; } @Column(name = "JOBGROUP") public String getJobGroup() { return jobGroup; } public void setJobGroup(String jobGroup) { this.jobGroup = jobGroup; } @Column(name = "JOBSTATUS") public String getJobStatus() { return jobStatus; } public void setJobStatus(String jobStatus) { this.jobStatus = jobStatus; } @Column(name = "CRONEXPRESSION") public String getCronExpression() { return cronExpression; } public void setCronExpression(String cronExpression) { this.cronExpression = cronExpression; } @Column(name = "DESCRIPTION") public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } @Column(name = "BEANCLASS") public String getBeanClass() { return beanClass; } public void setBeanClass(String beanClass) { this.beanClass = beanClass; } @Column(name = "ISCONCURRENT") public String getIsConcurrent() { return isConcurrent; } public void setIsConcurrent(String isConcurrent) { this.isConcurrent = isConcurrent; } @Column(name = "SPRINGID") public String getSpringId() { return springId; } public void setSpringId(String springId) { this.springId = springId; } @Column(name = "METHODNAME") public String getMethodName() { return methodName; } public void setMethodName(String methodName) { this.methodName = methodName; } }2.实现实体的dao层与service层,这里仅给出service接口的代码
public interface ScheduleJobService { List<ScheduleJob> findAll(); void save(ScheduleJob scheduleJob); void update(ScheduleJob scheduleJob); ScheduleJob findById(Integer id); }3.实现系统动态定时任务管理service接口和实现
public interface ScheduleJobManageService { /** * 添加任务 * * @param scheduleJob */ void addScheduleJob(ScheduleJob scheduleJob); /** * 暂停任务 * * @param scheduleJob */ void pauseScheduleJob(ScheduleJob scheduleJob); /** * 恢复任务 * * @param scheduleJob */ void resumeScheduleJob(ScheduleJob scheduleJob); /** * 删除任务 * * @param scheduleJob */ void deleteScheduleJob(ScheduleJob scheduleJob); /** * 立即执行任务 * * @param scheduleJob */ void runScheduleJobNow(ScheduleJob scheduleJob); /** * 更新任务 * * @param scheduleJob */ void updateSchedule(ScheduleJob scheduleJob); /** * 所有任务 * * @return */ List<ScheduleJob> getAllScheduleJob(); /** * 所有正在运行的任务 * * @return */ List<ScheduleJob> getAllScheduleJobRunning(); /** * 系统初始化添加计划任务 */ void init(); }
@Service @Transactional public class ScheduleJobManageServiceImpl implements ScheduleJobManageService { public final Logger logger = Logger.getLogger(getClass()); @Autowired private SchedulerFactoryBean schedulerFactoryBean; @Resource private ScheduleJobService scheduleJobService; @Override public void addScheduleJob(ScheduleJob scheduleJob) { if (scheduleJob == null || !Constants.SCHEDULEJOB_STATUS_RUNNING.equals(scheduleJob.getJobStatus())) { return; } Scheduler scheduler = schedulerFactoryBean.getScheduler(); logger.info("开始添加任务,任务:" + scheduleJob.getJobName()); try { TriggerKey triggerKey = TriggerKey.triggerKey(scheduleJob.getJobName(), scheduleJob.getJobGroup()); CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey); // 不存在,创建一个 if (trigger == null) { Class clazz = Constants.SCHEDULEJOB_CONCURRENT_IS.equals(scheduleJob.getIsConcurrent()) ? ScheduleJobFactory.class : ScheduleJobFactoryNotCurrent.class; JobDetail jobDetail = JobBuilder.newJob(clazz).withIdentity(scheduleJob.getJobName(), scheduleJob.getJobGroup()).build(); jobDetail.getJobDataMap().put("scheduleJob", scheduleJob); CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression()); trigger = TriggerBuilder.newTrigger().withIdentity(scheduleJob.getJobName(), scheduleJob.getJobGroup()).withSchedule(scheduleBuilder).build(); scheduler.scheduleJob(jobDetail, trigger); } else { // Trigger已存在,那么更新相应的定时设置 CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression()); // 按新的cronExpression表达式重新构建trigger trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build(); // 按新的trigger重新设置job执行 scheduler.rescheduleJob(triggerKey, trigger); } } catch (Exception e) { logger.error("添加任务出错,任务:" + scheduleJob.getJobName()); } logger.info("添加任务完成,任务:" + scheduleJob.getJobName()); } @Override public void pauseScheduleJob(ScheduleJob scheduleJob) { try { Scheduler scheduler = schedulerFactoryBean.getScheduler(); JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup()); scheduler.pauseJob(jobKey); } catch (Exception e) { logger.error("暂停任务出错,任务:" + scheduleJob.getJobName()); throw new MyException("暂停任务出错,任务:" + scheduleJob.getJobName(), e); } } @Override public void resumeScheduleJob(ScheduleJob scheduleJob) { try { Scheduler scheduler = schedulerFactoryBean.getScheduler(); JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup()); scheduler.resumeJob(jobKey); } catch (Exception e) { logger.error("恢复任务出错,任务:" + scheduleJob.getJobName()); throw new MyException("恢复任务出错,任务:" + scheduleJob.getJobName(), e); } } @Override public void deleteScheduleJob(ScheduleJob scheduleJob) { try { Scheduler scheduler = schedulerFactoryBean.getScheduler(); JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup()); scheduler.deleteJob(jobKey); } catch (Exception e) { logger.error("删除任务出错,任务:" + scheduleJob.getJobName()); throw new MyException("删除任务出错,任务:" + scheduleJob.getJobName(), e); } } @Override public void runScheduleJobNow(ScheduleJob scheduleJob) { try { Scheduler scheduler = schedulerFactoryBean.getScheduler(); JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup()); scheduler.triggerJob(jobKey); } catch (Exception e) { logger.error("立即启动任务出错,任务:" + scheduleJob.getJobName()); throw new MyException("立即启动任务出错,任务:" + scheduleJob.getJobName(), e); } } @Override public void updateSchedule(ScheduleJob scheduleJob) { try { Scheduler scheduler = schedulerFactoryBean.getScheduler(); TriggerKey triggerKey = TriggerKey.triggerKey(scheduleJob.getJobName(), scheduleJob.getJobGroup()); CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey); CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression()); trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build(); scheduler.rescheduleJob(triggerKey, trigger); } catch (Exception e) { logger.error("更新任务出错,任务:" + scheduleJob.getJobName()); throw new MyException("更新任务出错,任务:" + scheduleJob.getJobName(), e); } } @Override public List<ScheduleJob> getAllScheduleJob() { try { Scheduler scheduler = schedulerFactoryBean.getScheduler(); GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup(); Set<JobKey> jobKeys = scheduler.getJobKeys(matcher); List<ScheduleJob> jobList = new ArrayList<ScheduleJob>(); for (JobKey jobKey : jobKeys) { List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey); for (Trigger trigger : triggers) { ScheduleJob job = new ScheduleJob(); job.setJobName(jobKey.getName()); job.setJobGroup(jobKey.getGroup()); job.setDescription("触发器:" + trigger.getKey()); Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey()); job.setJobStatus(triggerState.name()); if (trigger instanceof CronTrigger) { CronTrigger cronTrigger = (CronTrigger) trigger; String cronExpression = cronTrigger.getCronExpression(); job.setCronExpression(cronExpression); } jobList.add(job); } } return jobList; } catch (Exception e) { logger.error("获取系统所有任务出错!"); throw new MyException("获取系统所有任务出错!", e); } } @Override public List<ScheduleJob> getAllScheduleJobRunning() { try { Scheduler scheduler = schedulerFactoryBean.getScheduler(); List<JobExecutionContext> executingJobs = scheduler.getCurrentlyExecutingJobs(); List<ScheduleJob> jobList = new ArrayList<ScheduleJob>(executingJobs.size()); for (JobExecutionContext executingJob : executingJobs) { ScheduleJob job = new ScheduleJob(); JobDetail jobDetail = executingJob.getJobDetail(); JobKey jobKey = jobDetail.getKey(); Trigger trigger = executingJob.getTrigger(); job.setJobName(jobKey.getName()); job.setJobGroup(jobKey.getGroup()); job.setDescription("触发器:" + trigger.getKey()); Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey()); job.setJobStatus(triggerState.name()); if (trigger instanceof CronTrigger) { CronTrigger cronTrigger = (CronTrigger) trigger; String cronExpression = cronTrigger.getCronExpression(); job.setCronExpression(cronExpression); } jobList.add(job); } return jobList; } catch (Exception e) { logger.error("获取系统所有正在运行任务出错!"); throw new MyException("获取系统所有正在运行任务出错!", e); } } @Override public void init() { // 这里获取任务信息数据 List<ScheduleJob> jobList = scheduleJobService.findAll(); for (ScheduleJob scheduleJob : jobList) { addScheduleJob(scheduleJob); } } }service实现需要调用的类
public class ScheduleJobFactory implements Job { @Override public void execute(JobExecutionContext context) throws JobExecutionException { ScheduleJob scheduleJob = (ScheduleJob) context.getMergedJobDataMap().get("scheduleJob"); ScheduleJobUtil.invokMethod(scheduleJob); } }
import org.quartz.DisallowConcurrentExecution; import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import com.tongdow.jianle.entity.ScheduleJob; @DisallowConcurrentExecution public class ScheduleJobFactoryNotCurrent implements Job { @Override public void execute(JobExecutionContext context) throws JobExecutionException { ScheduleJob scheduleJob = (ScheduleJob) context.getMergedJobDataMap().get("scheduleJob"); ScheduleJobUtil.invokMethod(scheduleJob); } }
public class ScheduleJobUtil { public final static Logger logger = Logger.getLogger(ScheduleJobUtil.class); /** * 通过反射调用scheduleJob中定义的方法 * * @param scheduleJob */ public static void invokMethod(ScheduleJob scheduleJob) { Object object = null; Class clazz = null; try { if (!Common.isNullOrEmpty(scheduleJob.getSpringId()) && SpringUtils.containsBean(scheduleJob.getSpringId())) { object = SpringUtils.getBean(scheduleJob.getSpringId()); } else if (!Common.isNullOrEmpty(scheduleJob.getBeanClass())) { clazz = Class.forName(scheduleJob.getBeanClass()); object = clazz.newInstance(); } if (object == null) { logger.error("任务:" + scheduleJob.getJobName() + ",结果:启动失败!"); return; } clazz = object.getClass(); Method method = null; method = clazz.getDeclaredMethod(scheduleJob.getMethodName()); if (method != null) { method.invoke(object); } else { logger.error("任务:" + scheduleJob.getJobName() + ",结果:启动失败!"); return; } logger.info("任务:" + scheduleJob.getJobName() + ",结果:启动成功!"); } catch (Exception e) { logger.error("任务:" + scheduleJob.getJobName() + ",结果:启动失败!,原因:" + e.getMessage()); throw new MyException("计划任务启动出错", e); } } }4.动态定时任务的执行方法
@Component public class JobTask { public Logger logger = Logger.getLogger(getClass()); @Resource private GoodsOrdersService goodsOrdersService; public void goodsOrder() { logger.info("商品订单处理定时任务开始!"); logger.info("商品订单处理定时任务结束!"); } public void order() { logger.info("订单处理定时任务开始!"); logger.info("订单处理定时任务结束!"); } }5.Spring配置文件需加入的内容
<bean id="springUtils" class="xxx" /><pre name="code" class="html"><!-- xxx为具体的类 -->
<!-- 任务调度器生成器,Spring生成具有指定属性调度器对象 --> <bean id="schedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <!-- 生成的调度器所管理的所有触发器 --> <property name="triggers"> <list> <ref bean="goodsOrder" /><!-- 项目发布定时任务 --> </list> </property> <property name="autoStartup" value="true" /> </bean> <!-- 触发器生成器类,用被指定的调度器调度生成指定规则的触发器对象 --> <bean id="goodsOrder" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <!-- 触发后要做的操作,这个操作由spring管理,只需要指定一个MethodInvokingJobDetailFactoryBean --> <property name="jobDetail" ref="goodsOrderJobDetail" /> <!-- 触发规则,这里的触发规则是每隔1分钟后触发一次 --> <property name="cronExpression" value="0 */1 * * * ?" /><!-- --> </bean> <!--任务生成器,由spring管理,只需要指定其对应的对象和方法即可,任务的执行即是某个对象调用一个方法 --> <bean id="goodsOrderJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> <!-- 指定该任务对应的调用对象,这个对象所属的类无需实现任何接口--> <property name="targetObject" ref="jobTask" /> <!-- 指定在targetObject对象中某个的方法 --> <property name="targetMethod" value="goodsOrder" /> <!-- 是否允许任务并发执行。当值为false时,表示必须等到前一个线程处理完毕后才再启一个新的线程 --> <property name="concurrent" value="false" /> </bean> <!-- 一个普通的类--> <bean id="jobTask" class="xxx同上"/>配置文件说明,如果只需要动态定时任务,则只需要
<bean id="schedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"/>
其他的为非动态定时任务如果配置了这个
<bean id="jobTask" class="xxx同上"/>则实体类可以springId字段可以指定jobTask,前提是执行任务的方法是写在这个bean里的。
6.用到的常量
/** * 常量定义 * * @author * */ public class Constants { // 计划任务 状态和是否有状态 public static final String SCHEDULEJOB_STATUS_RUNNING = "1";// 启动任务 public static final String SCHEDULEJOB_STATUS_NOT_RUNNING = "0";// 不启动任务 public static final String SCHEDULEJOB_CONCURRENT_IS = "1";// 有状态 public static final String SCHEDULEJOB_CONCURRENT_NOT = "0";// 无状态 }7.系统初始化
<span style="white-space:pre"> </span>logger.info("系统开始初始化"); <span style="white-space:pre"> </span>// 获取容器与相关的Service对象 <span style="white-space:pre"> </span>ApplicationContext ac = WebApplicationContextUtils.getWebApplicationContext(sce.getServletContext()); <span style="white-space:pre"> </span>ScheduleJobManageService scheduleJobManageService = ac.getBean(ScheduleJobManageService.class); <span style="white-space:pre"> </span>// 初始化系统动态定时任务 scheduleJobManageService.init(); logger.info("系统初始化完成");
结束,有问题可以qq135018413
相关文章推荐
- 在整合springmvc+mybatis+ecache时候报错如下: Another unnamed CacheManager already exists in the same VM.
- Java-正确使用equals和hashCode方法
- java poi excel
- Spring RMI调用远程方法
- SpringMVC 和 Struts2 框架区别
- Java HashMap工作原理及实现
- Spring 的@Component和@Autowired
- Spring中数据源的配置形式
- java中重载与重写的区别
- Spring的XML配置的bean调用注解方式的bean
- java 死记硬背真不行
- java 执行jar包引用别的jar包方式
- springmvc之数据验证
- java: Multiple encodings set for module chunk test "GBK" will be used by compiler
- 《JAVA与模式》之门面模式
- JAVA多态的汇总
- 深入理解Java:注解(Annotation)自定义注解入门
- eclipse开发erlang _安装,hello world
- 说说自己常用的jdk包?
- XML——写出XML文档(XSLT+StAX)