spring整合quartz的方法有两个 下面我们将用 MethodInvokingJobDetailFactoryBean进行整合一遍 任务类可以不实现Job接口,通过targetMethod指定调用方法-
1.引入pom文件中的依赖
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>
2.在你的spring.xml文件中引入bean
<!-- 任务调度器job -->
<bean id="checkSaleJob" class="com.dtyun.csfw.task.CheckSaleJob"/>
<!-- 使用MethodInvokingJobDetailFactoryBean,任务类可以不实现Job接口,通过targetMethod指定调用方法-->
<!-- jobDetail -->
<bean id="oceanJob" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="checkSaleJob"/>
<property name="targetMethod" value="check"/>
<!-- 上一次未执行完成的,要等待有再执行。 -->
<property name="concurrent" value="false"/>
</bean>
<!-- Trigger-->
<bean id="oceanStatusCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail" ref="oceanJob"/>
<!-- 时间设置 下面有解说。 -->
<property name="cronExpression" value="0/1 * * * * ?"/>
</bean>
<!--Scheduler -->
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="oceanStatusCronTrigger"/>
</list>
</property>
</bean>
3.直接在你的工程中写一个类 CheckSaleJob 这里说明一下 因为我的配置文件中配置的是targetMethod那儿的class路径可以自己换成自己的class类路径 那儿的targetMethod 配置的是我那个targetMethod类中的check的方法 所以也必须替换你们自己写的方法 不然不会生效
public class CheckSaleJob {
public void check() {
System.out.println("别跑,我tm是来检查工作的...."+System.currentTimeMillis());
//再加上你的业务逻辑 就像你工程的类一样 可以注入啥的都可以
}
}
4.quartz中的时间的设置 至少有6个字符(或者7个字符),空格作为间隔, 通常 0 * * * * * ?格式:
第一个字符是秒
第二个字符是分
第三个字符是时
第四个字符是天(0~31,但是你需要考虑你月的天数)
第五个字符是月
第六个字符(星期)(1~7 1=SUN 或 SUN,MON,TUE,WED,THU,FRI,SAT)
第七个字符是年
其中每个元素可以是一个值(如6),一个连续区间(9-12),一个间隔时间(8-18/4)(/表示每隔4小时),一个列表(1,3,5),通配符。由于"月份中的日期"和"星期中的日期"这两个元素互斥的,必须要对其中一个设置?.
0 0 10,14,16 * * ? 每天上午10点,下午2点,4点整触发
0 0/30 9-17 * * ? 朝九晚五工作时间内每半小时触发
0 0 12 ? * WED 表示每个星期三中午12点 触发
"0 0 12 * * ?" 每天中午12点触发
"0 15 10 ? * *" 每天上午10:15触发
"0 15 10 * * ?" 每天上午10:15触发
"0 15 10 * * ? *" 每天上午10:15触发
"0 15 10 * * ? 2005" 2005年的每天上午10:15触发
"0 * 14 * * ?" 在每天下午2点到下午2:59期间的每1分钟触发
"0 0/5 14 * * ?" 在每天下午2点到下午2:55期间的每5分钟触发
"0 0/5 14,18 * * ?" 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发
"0 0-5 14 * * ?" 在每天下午2点到下午2:05期间的每1分钟触发
"0 10,44 14 ? 3 WED" 每年三月的星期三的下午2:10和2:44触发
"0 15 10 ? * MON-FRI" 周一至周五的上午10:15触发
"0 15 10 15 * ?" 每月15日上午10:15触发
"0 15 10 L * ?" 每月最后一日的上午10:15触发
"0 15 10 ? * 6L" 每月的最后一个星期五上午10:15触发
"0 15 10 ? * 6L 2002-2005" 2002年至2005年的每月的最后一个星期五上午10:15触发
"0 15 10 ? * 6#3" 每月的第三个星期五上午10:15触发
下面
每隔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 * * ?
项目中用到的 下面说一下
0 0/5 * * * ? 五分钟执行一次
0 */5 * * * ? 那么这个就是在第五分钟到第六分钟 每秒都执行一次
直接复制上用吧 项目赶的可以直接复制上 用就完了.
最后发现quartz执行两遍的问题
第一次:web容器启动的时候,读取applicationContext.xml文件时,会加载一次。
第二次:Spring本身会加载applicationContext.xml一次。
而我的quartz配置就是写在applicationContext.xml文件里的。
解决办法很简单
先把quartz配置信息提取出来,单独存成一个文件,比如applicationContext-quartz.xml
然后修改web.xml,让web容器启动时,可以加载该文件
这样quartz只会在web容器启动时加载一次,Spring不会再加载了。
web.xml配置如下:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/classes/applicationContext.xml,/WEB-INF/classes/applicationContext-timertask.xml</param-value>
</context-param>
<!-- 开启监听 -->
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>