当前位置: 首页 > ds >正文

Spring整合Quartz框架实现定时任务跑批(Maven完整版)

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任务细节
Spring框架提供了对Quartz框架的支持,这对我们来说,方便了很多。我们还是通过Maven工程来演示。

1,pom.xml配置文件内容如下:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  <modelVersion>4.0.0</modelVersion>  <groupId>com.yangcq</groupId>  <artifactId>SpringQuartzTest</artifactId>  <version>1.0.0</version>  <packaging>jar</packaging>  <name>SpringQuartzTest</name>  <properties>  <springframework.version>4.0.6.RELEASE</springframework.version><!-- Spring的版本 --> <quartz.version>2.2.1</quartz.version>                          <!-- Quartz的版本 --> </properties>  <dependencies>  <dependency>  <groupId>org.springframework</groupId>  <artifactId>spring-core</artifactId>  <version>${springframework.version}</version>  </dependency>  <dependency>  <groupId>org.springframework</groupId>  <artifactId>spring-context-support</artifactId>  <version>${springframework.version}</version>  </dependency>  <!-- Spring事务的依赖 -->  <dependency>  <groupId>org.springframework</groupId>  <artifactId>spring-tx</artifactId>  <version>${springframework.version}</version>  </dependency>  <!-- 定时任务框架Quartz的依赖-->  <dependency>  <groupId>org.quartz-scheduler</groupId>  <artifactId>quartz</artifactId>  <version>${quartz.version}</version>  </dependency>  </dependencies>  
</project>  

2,定义我们自己的Job实现类。
Spring框架整合Quartz时,不是直接继承Job类,而是继承QuartzJobBean,
我们这里的一个实现如下:

package com.yangcq.quartz;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;
/*** * @author yangcq* @description 由于Spring提供对Quartz的支持,所以直接使用Spring提供的API* @description 继承  org.springframework.scheduling.quartz.QuartzJobBean**/
public class EBankJob extends QuartzJobBean {  /*** */private EBankJobBean eBankJobBean; @Overrideprotected void executeInternal(JobExecutionContext arg0) throws JobExecutionException {  eBankJobBean.printAnotherMessage();  }  public void setEBankJobBean(EBankJobBean eBankJobBean) {  this.eBankJobBean = eBankJobBean;  }  } 

这部分代码就是一个典型的spring注入,实际上调用了eBankJobBean的方法。具体job的执行是在executeInternal
方法里。
问题一:目前这种方法没有测试通过,分析一下什么原因?
问题二:MethodInvokingJobDetailFactoryBean 与 JobDetailBean 的区别,研究Spring源码
答:
1,QuartzJobBean是Spring框架下的一个抽象类,这个类实现了Quartz的Job接口。我们可以理解为,Spring对Job的
进一步封装,
public abstract class QuartzJobBean implements Job
2,JobDetailBean也是继承了Quartz下面的JobDetail接口,这里为什么是继承,本人也感到费解,按说JobDetail是
一个抽象接口,
应该用implements关键字实现这个接口,具体代码如下:
public class JobDetailBean extends JobDetail
3,MethodInvokingJobDetailFactoryBean,这个类为我们设置定时任务,提供了丰富的支持,如下:

  private String name;private String group;private boolean concurrent;private String targetBeanName;private String[] jobListenerNames;private String beanName;private ClassLoader beanClassLoader;private BeanFactory beanFactory;private JobDetail jobDetail;

package com.yangcq.quartz;
/*** * @author yangcq**/
public class EBankJobBean {public void printAnotherMessage(){  System.out.println("CronTriggerBean 调用的定时任务...");  }   
}

因为是要将这些任务通过spring的配置文件来拼接到一起,我们来看看具体的配置文件该怎么设置。
在spring里,如果我们要执行一个计划任务,需要定义一个JobDetail,用它来封装我们具体执行的任务。结合前面纯quartz的示例,
我们发现它们其实本质上是一样的。这里的定义如下:


spring默认提供了一个叫MethodInvokingJobDetailFactoryBean,我们需要将定义好的对象和需要调用的方法传给它。
这里对应的是一种类型的jobDetail定义。对应的myBean定义如下:

package com.yangcq.quartz;
/*** * @author yangcq* @description SimpleTriggerFactoryBean 调用的定时任务*/
public class MyJobBean {public void printMessage() {  System.out.println("SimpleTriggerFactoryBean 调用的定时任务...");  }    
}

OK,下面写一个测试类,进行测试

package com.yangcq.quartz;import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/*** * @author yangcq* @description 启动定时任务main方法**/
public class StartUpQuartzJobs {static final Log log = LogFactory.getLog(StartUpQuartzJobs.class); // 日志public static void main(String args[]) throws Exception {log.info("开始启动定时任务 ...");ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");  log.info("定时任务启动成功...");}
}

接下来就是关键部分了,Spring核心配置文件的的配置,配置文件applicationContext.xml配置如下:

<?xml version="1.0" encoding="UTF-8"?>  
<!-- Bean头部 -->  
<beans xmlns="http://www.springframework.org/schema/beans"  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xmlns:p="http://www.springframework.org/schema/p"  xmlns:mvc="http://www.springframework.org/schema/mvc"  xmlns:context="http://www.springframework.org/schema/context"  xmlns:util="http://www.springframework.org/schema/util"  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd  http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd">  <!-- 启动包扫描功能,以便注册带有@Controller、@Service、@repository、@Component等注解的类成为spring的bean -->   <context:component-scan base-package="com.yangcq.quartz" /> <bean id="myJobBean" class="com.yangcq.quartz.MyJobBean"></bean><bean id="eBankJobBean" class="com.yangcq.quartz.EBankJobBean"></bean><bean id="simpleJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">  <property name="targetObject" ref="myJobBean" />  <property name="targetMethod" value="printMessage" />  </bean>  <!-- 这种封装的方式很简单,就是我定义了一个对象和它对应的方法。如果我们需要将它们封装成一个job了,只要把类的名字和 --><!-- 对应的方法传进去就可以了。除了上述的JobDetail构造方式,还要一种更复杂一些,它的定义如下: --><!--   这里因为要用到一些对象的引用,对这些对象或者参数的传递可以通过jobDataMap来处理。 --><bean name="complexJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">  <property name="targetObject" ref="eBankJobBean" />  <property name="targetMethod" value="printAnotherMessage" /> </bean> <!-- Spring提供了2中触发器:SimpleTriggerBean 和 CronTriggerBean --><!-- Trigger触发器 :从第1秒开始,每3秒执行一次 --><bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">  <property name="jobDetail" ref="simpleJobDetail" />  <property name="startDelay" value="1000" /><property name="repeatInterval" value="3000" />  </bean>  <!-- Trigger触发器 :从第1秒开始,每5秒执行一次 --><bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">  <property name="jobDetail" ref="complexJobDetail" />  <property name="cronExpression" value="0/5 * * * * ?" />  </bean>  <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">  <property name="jobDetails">  <list>  <ref bean="simpleJobDetail" />  <ref bean="complexJobDetail" />  </list>  </property>  <property name="triggers">  <list>  <ref bean="simpleTrigger" />  <ref bean="cronTrigger" />  </list>  </property>  </bean>    
</beans> 

启动程序以后,控制台输出如下:
log4j:WARN No appenders could be found for logger (com.yangcq.quartz.StartUpQuartzJobs).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
SimpleTriggerFactoryBean 调用的定时任务...
CronTriggerBean 调用的定时任务...
SimpleTriggerFactoryBean 调用的定时任务...
CronTriggerBean 调用的定时任务...
SimpleTriggerFactoryBean 调用的定时任务...

总结
在这两个示例里,我们首先通过一个纯手工的过程来完成一个任务调度的示例。它的主要步骤为
1.定义job
2. 定义trigger
3. 定义scheduler来拼接。
在后续使用spring的示例里,其实也是这么一个步骤,只不过spring提供了一些实现的支持,需要在配置文件里指定
不同的jobDetail类型和trigger类型。
 

http://www.xdnf.cn/news/11139.html

相关文章:

  • 超级详细的GitLab安装 与使用 【Gitlab添加组、创建用户和项目、权限管理】_gitlab群组
  • 探秘GPT:开启人工智能语言模型的新纪元
  • Yandex 邮箱添加
  • 麒麟短线王至尊版 软件及指标 应用!
  • Linux系统下安装部署Linux管理面板1panel
  • Win11系统提示找不到olecli32.dll文件的解决办法
  • web.xml中context-param的配置作用
  • dll和so文件区别与构成
  • 世界环保创业基金会简介
  • LDAP 目录服务器的现代化应用
  • 动态实现RelativeLayout,LinearLayout布局
  • Lenovo笔记本新版Veriface Pro(人像识别)软件介绍
  • InstallShield 12 制作安装包
  • anaconda安装gdal、Fiona、shapely、pyproj、geopandas
  • size mismatch: error 在搭建网络的时候
  • 使用JavaScript实现选项卡
  • java内存区域理解-初步了解
  • 洛谷 P2452 [SDOI2005] 屠龙传说-屠龙枪卷
  • 2022-04-30 Unity核心2——Sprite
  • 10种用于渗透测试的漏洞扫描工具有哪些_渗透测试和漏洞扫描区别_渗透漏洞分级工具
  • Android2.2快速入门
  • 13种网页QQ代码
  • MFC自绘入门(一)
  • 华硕电脑无法安装Ubuntu 11.04(10.10同)
  • 作为程序员,我都逛了哪些技术网站?(收藏篇)
  • 将小游戏打包成单一exe文件的原理及应用
  • 修改固态硬盘的物理序列号_电脑突然断电,固态硬盘无法识别怎么办?
  • tracert 路由跟踪
  • Authorware使用案例:DirectMediaXtra制作内部媒体播放器
  • 2024年九个简单易用的wordpress主题模板网站推荐