Spring 的定时任务--Quartz

本文详细介绍如何使用Spring框架结合Quartz实现定时任务,包括项目搭建步骤、配置详解及优化方案,并解析Cron表达式的使用。

一. 应用场景

在我们进行软件开发过程中,会遇到这样的场景,比如在凌晨的时候进行数据的统一刷新;每个月末进行用户数据的统计;定期清理不用的数据等等,这时候就要用到定时任务来进行处理了

二.实现技术

从 技术上说实现定时任务常见的方法有三种

  • Java自带的java.util.Timer类
  • 使用Quartz调度器,这种方式需要第三方jar支持
  • Spring3.0以后自带的task定时器

由于目前项目中spring框架应用的非常广泛,故本文将直接介绍与spring结合的Quartz定时任务技术。采用普通类+xml配置文件的方式进行多个定时任务的启动。

三.项目搭建

1. 创建maven项目

173321_In5J_2950677.png

转换添加web.xml文件

173221_vx1T_2950677.png

pom.xml文件

174543_SFt7_2950677.png

2. 在web.xml 中添加监听器

 <!-- needed for ContextLoaderListener -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>/WEB-INF/classes/spring/application-context.xml</param-value>
	</context-param>

	<!-- Bootstraps the root web application context before servlet initialization -->
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>

3.添加spring-context.xml文件和编写定时任务类QuartOne以及QuartzTwo两个类

173647_XCi4_2950677.png173810_Ng01_2950677.png

4. 添加配置文件

 4.1 由于是与Quartz结合故pom.xml 中要添加quartz的相关jar包

174817_FmO7_2950677.png

4.2 spring-context.xml 中配置内容

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:util="http://www.springframework.org/schema/util" xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
		http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
		http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-3.0.xsd">
	
		<!-- 注册任务的类 -->
	  <bean id="one" class="com.xing.deng.QuartzOne"/>
	  <bean id="two" class="com.xing.deng.QuartzTwo"/>
	  
	 <!-- 1:定时任务 start-->
	  <bean id="oneDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean" >
	    <!-- 指定任务类 --> 
	  	<property name="targetObject" ref="one"/>
	  	<!-- 指定任务执行的方法 -->
	  	<property name="targetMethod" value="execute"/>
	  	 <!-- 不并发调度 -->
	  	<property name="concurrent" value="false"></property>
	  </bean>
	  	<bean id="oneCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
	  		<property name="jobDetail" ref="oneDetail"/>
	  		 <property name="cronExpression" value="0/10 * * * * ?" />  
	  	</bean>
	  	<!-- 1:定时任务 end -->
	  	
	  	<!-- 2:定时任务 start -->
	  	
	  <bean id="twoDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean" >
	    <!-- 指定任务类 --> 
	  	<property name="targetObject" ref="two"/>
	  	<!-- 指定任务执行的方法 -->
	  	<property name="targetMethod" value="execute"/>
	  	<property name="concurrent" value="false"></property>
	  </bean>
	  	<bean id="twoCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
	  		<property name="jobDetail" ref="twoDetail"/>
	  		 <property name="cronExpression" value="0/10 * * * * ?" />  
	  	</bean>
	  	<!-- 2:定时任务 end -->
	  	<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
	  		<property name="triggers">
	  			<list>
	  				<ref bean="oneCronTrigger"/>
	  				<ref bean="twoCronTrigger"/>
	  			</list>
	  		</property>
	  	</bean>
</beans>

4.3 配置说明

180635_0g7O_2950677.png

180719_UNUD_2950677.png

注意上面的标注一定要一一对应!!!

5. 启动tomcat后执行结果

180839_lDUP_2950677.png

参考来源:http://blog.youkuaiyun.com/harry_zh_wang/article/details/60782780

 

6.项目优化

6.1  目标

针对上面的定时任务,我们是否可以定义这样一个抽象的类,统一固定的执行任务方法,那么其他的定时任务只需继承这个抽象类,那样就能避免项目中每个人写不同的定时任务执行方法了(这种方式在java中就是叫做:抽象)。

既然目的清楚,那我们就开始coding.

6.2 搭建

创建抽象类 :AbstractQuartz

142104_e1YI_2950677.png

创建子类:FirstQuartz 和SecondQuartz

141827_eFlZ_2950677.png

142138_wkLM_2950677.png

编写配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:util="http://www.springframework.org/schema/util" xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
		http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
		http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-3.0.xsd">
	
		<!-- 1. 注册任务的类 -->
	  <bean id="firstQuartz" class="com.xing.deng.quartz.FirstQuartz"/>
	  <bean id="secondQuartz" class="com.xing.deng.quartz.SecondQuartz"/>
	  
	  <!--2.  配置作业类 -->
	  <bean id="abstractQuartzDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean" abstract="true">
	  	 <property name="targetMethod" value="handler"/>
	  </bean>
	  <bean id="abstractTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean" abstract="true"/>
	  
	  <!--3.  配置任务调度触发器 -->
	 <bean id="firstTrigger" parent="abstractTrigger">
	 	<property name="jobDetail">
	 		<bean parent="abstractQuartzDetail">
	 			<property name="targetObject" ref="firstQuartz"/>
	 		</bean>
	 	</property>
	 	<property name="cronExpression" value="0/10 * * * * ?" />
	 </bean>
	 
	 <bean id="secondTrigger" parent="abstractTrigger">
	 	<property name="jobDetail">
	 		<bean parent="abstractQuartzDetail">
	 			<property name="targetObject" ref="secondQuartz"/>
	 		</bean>
	 	</property>
	 	<property name="cronExpression" value="0/10 * * * * ?" />
	 </bean>
	 
	 <!--4. 配置任务调度工厂 -->
	 <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
	 	<property name="triggers">
	 		<list>
	 			<ref bean="firstTrigger"/>
	 			<ref bean="secondTrigger"/>
	 		</list>
	 	</property>
	 </bean>
</beans>

说明:

143143_e5JZ_2950677.png

 我们通过配置文件可以看到,在配置作业类的时候,增加了  abstract="true"  ,同时其他任务出发器只需注明父类即可统一执行指定的方法,是不是觉得这样的方式十分的统一方便

143610_rlH5_2950677.png

7. cron 表达式

说明:

         1)Cron表达式的格式:秒 分 时 日 月 周 年(可选)。

               字段名                 允许的值                        允许的特殊字符  

               秒                         0-59                               , - * /  

               分                         0-59                               , - * /  

               小时                   0-23                               , - * /  

               日                         1-31                               , - * ? / L W C  

               月                         1-12 or JAN-DEC          , - * /  

               周几                     1-7 or SUN-SAT            , - * ? / L C #  

               年 (可选字段)     empty, 1970-2099      , - * /

               “?”字符:表示不确定的值

               “,”字符:指定数个值

               “-”字符:指定一个值的范围

               “/”字符:指定一个值的增加幅度。n/m表示从n开始,每次增加m

               “L”字符:用在日表示一个月中的最后一天,用在周表示该月最后一个星期X

               “W”字符:指定离给定日期最近的工作日(周一到周五)

               “#”字符:表示该月第几个周X。6#3表示该月第3个周五

         2)Cron表达式范例:

                 每隔5秒执行一次:*/5 * * * * ?

                 每隔1分钟执行一次:0 */1 * * * ?

                 每天23点执行一次:0 0 23 * * ?

                 每天凌晨1点执行一次:0 0 1 * * ?

                 每月1号凌晨1点执行一次:0 0 1 1 * ?

                 每月最后一天23点执行一次:0 0 23 L * ?

                 每周星期天凌晨1点实行一次:0 0 1 ? * L

                 在26分、29分、33分执行一次:0 26,29,33 * * * ?

                 每天的0点、13点、18点、21点都执行一次:0 0 0,13,18,21 * * ?

 

转载于:https://my.oschina.net/newdeng/blog/1576923

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值