项目需求:
http://www.cnblogs.com/Alandre/p/3733249.html
上一博客写的是基本调度,后来这只能用于,像每天定个时间 进行数据库备份。但是,远远不能在上次的需求上实现。所以需要实现spring4.0 整合 Quartz 实现动态任务调度。
正文
spring4.0 整合 Quartz 实现任务调度。这真是期末项目的最后一篇,剩下到暑假吧。
Quartz 介绍
Quartz is a full-featured, open source job scheduling service that can be integrated with, or used along side virtually any Java application - from the smallest stand-alone application to the largest e-commerce system. Quartz can be used to create simple or complex schedules for executing tens, hundreds, or even tens-of-thousands of jobs;
Quartz框架是一个全功能、开源的任务调度服务,可以集成几乎任何的java应用程序—从小的单片机系统到大型的电子商务系统。Quartz可以执行上千上万的任务调度。
核心概念
Quartz核心的概念:scheduler任务调度、Job任务、Trigger触发器、JobDetail任务细节
回顾
上次我们配置了
<!--Quartz--> <!-- 集成方式:JobDetailFactoryBean,并且任务类需要继承QuartzJobBean--> <!-- 定义jobDetail --> <bean id="jobDetail" class="org.springframework.scheduling.quartz.JobDetailFactoryBean"> <!-- durability 表示任务完成之后是否依然保留到数据库,默认false --> <property name="durability" value="true" /> <!-- 目标类 /wmuitp/src/test/SpringQuartz.java--> <property name="jobClass" value="test.SpringQuartzTest"></property> <!-- 在这个例子中,jobDataAsMap没有用,此目标类中接受的参数 ,若参数为service,则可以在此进行参数配置,类似struts2 --> <!-- <property name="jobDataAsMap"> <map> <entry key="service"><value>simple is the beat</value></entry> </map> </property> --> </bean> <!-- 定义simpleTrigger触发器 --> <!-- <bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean"> <property name="jobDetail" ref="jobDetail"></property> <property name="repeatCount"> <value>8</value> </property> <property name="repeatInterval"> <value>1000</value> </property> <property name="startDelay"> <value>4</value> </property> </bean> --> <!-- 另一种触发器是CornTrigger --> <bean id="cornTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <property name="jobDetail" ref="jobDetail"/> <!-- 每个10秒触发 --> <property name="cronExpression" value="0/10 * * * * ?"/> </bean> <!-- 定义核心调度器 --> <bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="triggers"> <ref bean="cornTrigger"/> </property> </bean>
#spring实现quartz的方式,先看一下上面配置文件中定义的jobDetail。在Quartz 2.x版本中JobDetail已经是一个接口,Spring是通过将其转换为MethodInvokingJob或StatefulMethodInvokingJob类型来实现的。
这是文档中的源码:
/** * This implementation applies the passed-in job data map as bean property * values, and delegates to <code>executeInternal</code> afterwards. * @see #executeInternal */ public final void execute(JobExecutionContext context) throws JobExecutionException { try { // Reflectively adapting to differences between Quartz 1.x and Quartz 2.0... Scheduler scheduler = (Scheduler) ReflectionUtils.invokeMethod(getSchedulerMethod, context); Map mergedJobDataMap = (Map) ReflectionUtils.invokeMethod(getMergedJobDataMapMethod, context); BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this); MutablePropertyValues pvs = new MutablePropertyValues(); pvs.addPropertyValues(scheduler.getContext()); pvs.addPropertyValues(mergedJobDataMap); bw.setPropertyValues(pvs, true); } catch (SchedulerException ex) { throw new JobExecutionException(ex); } executeInternal(context); } /** * Execute the actual job. The job data map will already have been * applied as bean property values by execute. The contract is * exactly the same as for the standard Quartz execute method. * @see #execute */ protected abstract void executeInternal(JobExecutionContext context) throws JobExecutionException;
MethodInvokingJobDetailFactoryBean中的源码:
public void afterPropertiesSet() throws ClassNotFoundException, NoSuchMethodException { prepare(); // Use specific name if given, else fall back to bean name. String name = (this.name != null ? this.name : this.beanName); // Consider the concurrent flag to choose between stateful and stateless job. Class jobClass = (this.concurrent ? MethodInvokingJob.class : StatefulMethodInvokingJob.class); // Build JobDetail instance. if (jobDetailImplClass != null) { // Using Quartz 2.0 JobDetailImpl class... this.jobDetail = (JobDetail) BeanUtils.instantiate(jobDetailImplClass); BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this.jobDetail); bw.setPropertyValue("name", name); bw.setPropertyValue("group", this.group); bw.setPropertyValue("jobClass", jobClass); bw.setPropertyValue("durability", true); ((JobDataMap) bw.getPropertyValue("jobDataMap")).put("methodInvoker", this); } else { // Using Quartz 1.x JobDetail class... this.jobDetail = new JobDetail(name, this.group, jobClass); this.jobDetail.setVolatility(true); this.jobDetail.setDurability(true); this.jobDetail.getJobDataMap().put("methodInvoker", this); } // Register job listener names. if (this.jobListenerNames != null) { for (String jobListenerName : this.jobListenerNames) { if (jobDetailImplClass != null) { throw new IllegalStateException("Non-global JobListeners not supported on Quartz 2 - " + "manually register a Matcher against the Quartz ListenerManager instead"); } this.jobDetail.addJobListener(jobListenerName); } } postProcessJobDetail(this.jobDetail); }
#既然知道了其所以然,我们就可以真正实战了。
实战
听我慢慢道来
减少spring的配置文件
为了实现一个定时任务,spring的配置代码太多了。动态配置需要们手动来搞。这里我们只需要这要配置即可:
<!-- quartz配置 动态配置所以我们将 Factory 作为一个service一样的接口 QuartzJobFactory.java--> <!-- 调度工厂 --> <bean id="schedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> </bean>
Job实现类
在这里我把它看作工厂类:
package test; import org.quartz.DisallowConcurrentExecution; import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; @DisallowConcurrentExecution public class QuartzJobFactoryImpl implements Job { @Override public void execute(JobExecutionContext context) throws JobExecutionException { System.out.println("任务成功运行"); ScheduleJob scheduleJob = (ScheduleJob)context.getMergedJobDataMap().get("scheduleJob"); System.out.println("任务名称 = [" + scheduleJob.getJobName() + "]"); }
}
任务对应实体类
package test; public class ScheduleJob { /** 任务id **/ private String jobId; /** 任务名称 **/ private String jobName; /** 任务分组 **/ private String jobGroup; /** 任务状态 0禁用 1启用 2删除**/ private String jobStatus; /** 任务运行时间表达式 **/ private String cronExpression; /** 任务描述 **/ private String desc; public String getJobId() { return jobId; } public void setJobId(String jobId) { this.jobId = jobId; } public String getJobName() { return jobName; } public void setJobName(String jobName) { this.jobName = jobName; } public String getJobGroup() { return jobGroup; } public void setJobGroup(String jobGroup) { this.jobGroup = jobGroup; } public String getJobStatus() { return jobStatus; } public void setJobStatus(String jobStatus) { this.jobStatus = jobStatus; } public String getCronExpression() { return cronExpression; } public void setCronExpression(String cronExpression) { this.cronExpression = cronExpression; } public String getDesc() { return desc; } public void setDesc(String desc) { this.desc = desc; } }
下面我们就来测试下:
Controller 测试代码:
@RequestMapping(value = "/quartz") public ModelAndView quartz() throws SchedulerException { //schedulerFactoryBean 由spring创建注入 ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); System.out.println(ctx); Scheduler scheduler = (Scheduler)ctx.getBean("schedulerFactoryBean"); System.out.println(scheduler); //这里获取任务信息数据 List<ScheduleJob> jobList = new ArrayList<ScheduleJob>(); for (int i = 0; i < 3; i++) { ScheduleJob job = new ScheduleJob(); job.setJobId("10001" + i); job.setJobName("JobName_" + i); job.setJobGroup("dataWork"); job.setJobStatus("1"); job.setCronExpression("0/5 * * * * ?"); job.setDesc("数据导入任务"); jobList.add(job); } for (ScheduleJob job : jobList) { TriggerKey triggerKey = TriggerKey.triggerKey(job.getJobName(), job.getJobGroup()); //获取trigger,即在spring配置文件中定义的 bean id="myTrigger" CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey); //不存在,创建一个 if (null == trigger) { JobDetail jobDetail = JobBuilder.newJob(QuartzJobFactoryImpl.class) .withIdentity(job.getJobName(), job.getJobGroup()).build(); jobDetail.getJobDataMap().put("scheduleJob", job); //表达式调度构建器 CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job .getCronExpression()); //按新的cronExpression表达式构建一个新的trigger trigger = TriggerBuilder.newTrigger().withIdentity(job.getJobName(), job.getJobGroup()).withSchedule(scheduleBuilder).build(); scheduler.scheduleJob(jobDetail, trigger); } else { // Trigger已存在,那么更新相应的定时设置 //表达式调度构建器 CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job .getCronExpression()); //按新的cronExpression表达式重新构建trigger trigger = trigger.getTriggerBuilder().withIdentity(triggerKey) .withSchedule(scheduleBuilder).build(); //按新的trigger重新设置job执行 scheduler.rescheduleJob(triggerKey, trigger); } } ModelAndView mav = new ModelAndView(AdminWebConstant.ADMIN_LOGIN_VIEW); return mav; }
#后面这块应该会进一步整理。到时候 会出个更详细的。期待吧
测试结果:
总结
spring quartz
感谢及资源共享
http://www.cnblogs.com/Alandre/p/3735072.html
相关推荐
本篇文章将详细探讨如何在Spring Boot项目中整合Quartz,并通过MySQL数据库实现定时任务的动态配置。 首先,我们需要在项目中添加依赖。在Spring Boot的`pom.xml`文件中,引入Spring Boot的`spring-boot-starter-...
Spring框架作为Java领域广泛使用的轻量级框架,提供了与第三方库Quartz的整合,使得开发者能够轻松地在Spring应用中实现复杂的定时任务调度。Quartz是一款开源的作业调度框架,支持丰富的调度策略,可以满足各种定时...
可以通过quartz和spring的简单配置即可完成,但如果要改变任务的执行时间、频率,废弃任务等就需要改变配置甚至代码需要重启服务器,这里介绍一下如何通过quartz与spring的组合实现动态的改变定时任务的状态的一个...
基于Spring Boot和Quartz的分布式任务调度系统 项目简介 本项目是一个基于Spring Boot和Quartz框架的分布式任务调度系统,旨在提供一个灵活、可扩展的任务调度解决方案。系统支持多种任务类型,包括RPC任务、Cron...
在本文中,我们将详细介绍如何将 Spring 整合任务调度框架 Quartz,从而实现任务调度的自动化。 一、使用配置文件方式整合 Quartz 在 Spring 中,可以使用配置文件方式来整合 Quartz。这种方式非常简单,开发者只...
Spring 3整合Quartz 1.8实现定时任务三:动态暂停 恢复 修改和删除任务 ...注:spring3+quartz2动态任务调度,任务保存在内存中,页面显示动态管理版地址为http://download.csdn.net/detail/johnjobs/7646011
在这个“quartz_springbatch_dynamic”项目中,我们将看到如何将这两个强大的工具结合起来,以实现动态集群环境中的定时任务执行,并使用MySQL作为数据存储。 Quartz是一个开源的作业调度框架,允许开发者创建、...
通过理解和掌握这些知识点,开发者能够有效地在 Spring 2 和 Quartz 之间建立桥梁,实现 Web 应用中的复杂任务调度功能。对于出现问题的整合,开发者可以通过分析源码、查看日志和调试来定位和解决问题,进一步提升...
Spring框架和Quartz是两个广泛使用的工具,它们可以协同工作以实现复杂和灵活的任务调度。本篇文章将深入探讨如何使用Spring与Quartz结合来创建一个任务调度的小例子。 首先,Spring是一个开源的Java企业级应用开发...
Spring和Quartz是两个强大的工具,可以协同工作来实现动态管理的定时任务。本文将深入探讨如何利用Spring框架和Quartz库创建和管理这些任务。 **Spring框架** 是一个广泛应用的Java企业级开发框架,它提供了丰富的...
本资源是一个最新 Spring 4.2.2 集成 Quartz Scheduler 2.2.2 的一个简单的 demo,也是博客《最新 Spring 4.2.2 集成 Quartz Scheduler 2.2.2 任务调度示例》的配套示例项目,该博客地址是:...
Spring中的任务调度是实现应用程序自动化运行任务的重要工具,而Quartz是Java领域广泛使用的开源任务调度框架。在本文中,我们将深入探讨如何在Spring中集成Quartz进行任务调度,并通过一个简单的示例来理解其工作...
SpringBoot整合Quartz实现定时任务调度是企业级应用中常见的需求,主要用于自动化执行某些周期性的任务,例如数据备份、报表生成、系统维护等。Quartz是一个功能强大的开源作业调度框架,能够灵活地定义任务和调度...
本篇文章将详细探讨如何在SpringBoot项目中整合Quartz,实现动态配置定时任务。 首先,我们需要在SpringBoot项目中引入Quartz的相关依赖。在`pom.xml`文件中添加以下Maven依赖: ```xml <groupId>org.spring...
本文将深入探讨如何在SpringBoot 2.0.1版本中整合Quartz,实现动态定时任务,并结合MyBatis-Plus进行数据操作。 首先,我们要在SpringBoot项目中引入Quartz和MyBatis-Plus的依赖。在`pom.xml`文件中,添加如下依赖...
总的来说,`Spring Timer`适合简单的定时任务需求,而`Quartz Scheduler`更适合处理大型项目或需要高级调度功能的场景。在实际应用中,开发者可以根据项目需求选择合适的任务调度器。通过`spring-taskScheduling`这...
【标题】:基于Spring Boot和Quartz的分布式任务调度系统 在现代企业级应用中,任务调度是一项重要的功能,...通过这个项目,开发者可以深入学习和实践Spring Boot与Quartz的整合,以及分布式环境下的任务调度策略。
这个"spring-quartz-demo"项目就是一个很好的示例,它展示了如何在Spring中整合Quartz以实现动态定时任务。 首先,我们要了解Spring和Quartz的基本概念。Spring是一个全面的Java企业级应用开发框架,它提供了依赖...
本示例将探讨如何将 Spring 3 与 Quartz 1.8 和 2.2 版本进行整合,以实现高效的任务调度。 首先,我们来看 Spring 3 整合 Quartz 1.8 的步骤: 1. **引入依赖**:在项目中添加 Quartz 和 Spring 相关的库,确保...
在本例中,我们将探讨如何利用 Quartz 实现动态任务定时调度,特别是在一个 Spring、Hibernate 和 WebWork 集成的环境中。 首先,为了在项目中使用 Quartz,你需要从官方网站或通过 Maven/Gradle 下载 Quartz 的 ...