先介绍:Spring3.0以后自主开发的定时任务工具,spring task,可以将它比作一个轻量级的Quartz,而且使用起来很简单
1编写需要定时执行的类和方法
@Component
public class TaskJobTest {
public void taskJobAsdfMethod(){
System.out.println("tastJob...........每一分钟执行一次");
}
}
2.XML配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:task="http://www.springframework.org/schema/task"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.1.xsd">
<!-- Spring3.0以后自主开发的定时任务工具,spring task,可以将它比作一个轻量级的Quartz,而且使用起来很简单 -->
<task:scheduler id="myScheduler1" />
<task:scheduled-tasks scheduler="myScheduler1">
<!-- 每一分钟执行一次
cron表达式主要是用在Quartz框架中,Quartz是一个完全由java编写的开源作业调度框架,最主要的功能就是调度器(完成定时任务)
ref 执行定时器方法的类( javaBean)
method (类中执行的)方法
-->
<task:scheduled ref="taskJobTest" method="taskJobAsdfMethod" cron="0 0/1 * * * ?"/>
</task:scheduled-tasks>
</beans>
但是我们重点是是这种方案:使用quartz的与spring集成的定时器,也是重点推荐使用的:
<dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>2.2.3</version> </dependency>
1.每隔指定时间则触发一次,在Quartz中对应的触发器为:org.springframework.scheduling.quartz.SimpleTriggerBean
<!-- quartz 和spring集成方式 -->
<!-- 1:SimpleTrigger 每隔指定时间则触发一次,在Quartz中对应的触发器为:org.springframework.scheduling.quartz.SimpleTriggerBean -->
<!-- MethodInvokeJobDetailFactoryBean -->
<bean id="quartzModInk" class="com.demo.qz.QuartzMentod2Test" ></bean>
<bean id="quartzModInkJob" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean" >
<property name="targetObject" ref="quartzModInk" ></property>
<property name="targetMethod" value="doSomething"></property>
<!-- concurrent 同时发生
MethodInvokingJobDetailFactoryBean类默认是并发执行的,这时候如果不设置“concurrent”为false,很可能带来并发或者死锁的问题,而且几率较小,不容易复现,请大家使用的时候注意设置“concurrent”。
concurrent:对于相同的JobDetail,当指定多个Trigger时, 很可能第一个job完成之前,第二个job就开始了。
定concurrent设为false,多个job不会并发运行,第二个job将不会在第一个job完成之前开始 -->
<property name="concurrent" value="false"></property>
</bean>
<bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
<property name="jobDetail" ref="quartzModInkJob"></property>
<property name="startDelay" value="10000"></property> <!-- 调度工厂实例化后,经过多少(startDelay)毫秒秒开始执行调度 -->
<property name="repeatInterval" value="5000"></property><!-- 每(repeatInterval)毫秒调度一次 -->
</bean>
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<!-- <property name="jobFactory" ref="bsQuartzJobFactory"></property -->
<property name="triggers">
<list>
<ref bean="simpleTrigger" />
</list>
</property>
</bean>
java类为:
//MethodInvokeJobDetailFactoryBean
/*
* MethodInvokeJobDetailFactoryBean这又是一种定时器方式
* 但是这种方式注入起来,相当容易,并且不需要继承任何类或者实现任何接口
*/
public class QuartzMentod2Test {
public void doSomething(){
System.out.println("MethodInvokeJobDetailFactoryBean 每5秒");
}
}
每到指定时间则触发一次,在Quartz中对应的调度器为:org.springframework.scheduling.quartz.CronTriggerBean
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:task="http://www.springframework.org/schema/task"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.1.xsd">
<!-- Spring3.0以后自主开发的定时任务工具,spring task,可以将它比作一个轻量级的Quartz,而且使用起来很简单 -->
<task:scheduler id="myScheduler1" />
<task:scheduled-tasks scheduler="myScheduler1">
<!-- 每一分钟执行一次
cron表达式主要是用在Quartz框架中,Quartz是一个完全由java编写的开源作业调度框架,最主要的功能就是调度器(完成定时任务)
ref 执行定时器方法的类( javaBean)
method (类中执行的)方法 -->
<task:scheduled ref="taskJobTest" method="taskJobAsdfMethod" cron="0 0/1 * * * ?"/>
</task:scheduled-tasks>
<!-- quartz 和spring集成方式 -->
<!-- 1:SimpleTrigger 每隔指定时间则触发一次,在Quartz中对应的触发器为:org.springframework.scheduling.quartz.SimpleTriggerBean -->
<!-- MethodInvokeJobDetailFactoryBean -->
<bean id="quartzModInk" class="com.demo.qz.QuartzMentod2Test" ></bean>
<bean id="quartzModInkJob" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean" >
<property name="targetObject" ref="quartzModInk" ></property>
<property name="targetMethod" value="doSomething"></property>
<!-- concurrent 同时发生
MethodInvokingJobDetailFactoryBean类默认是并发执行的,这时候如果不设置“concurrent”为false,很可能带来并发或者死锁的问题,而且几率较小,不容易复现,请大家使用的时候注意设置“concurrent”。
concurrent:对于相同的JobDetail,当指定多个Trigger时, 很可能第一个job完成之前,第二个job就开始了。
定concurrent设为false,多个job不会并发运行,第二个job将不会在第一个job完成之前开始 -->
<property name="concurrent" value="false"></property>
</bean>
<bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
<property name="jobDetail" ref="quartzModInkJob"></property>
<property name="startDelay" value="10000"></property> <!-- 调度工厂实例化后,经过多少(startDelay)毫秒秒开始执行调度 -->
<property name="repeatInterval" value="500000"></property><!-- 每(repeatInterval)毫秒调度一次 -->
</bean>
<bean id="bsQuartzJobFactory" class="com.demo.qz.BsQuartzJobFactory"></bean>
<bean id="jobDetail"
class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="jobClass" value="com.demo.qz.BaseQuartzJobBean"></property>
<property name="durability" value="true"></property>
</bean>
<bean id="cronTrigger"
class="org.springframework.scheduling.quartz.CronTriggerFactoryBean ">
<property name="jobDetail" ref="jobDetail" />
<property name="cronExpression" value="0 0/3 * * * ?" />
</bean>
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="jobFactory" ref="bsQuartzJobFactory"></property>
<property name="triggers">
<list>
<ref bean="cronTrigger" />
<ref bean="simpleTrigger" />
</list>
</property>
</bean>
</beans>
继承QuartzJobBean类,定义jobDetail,但是如果我们注入其他的service时会出现问题,下面展示解决办法
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.QuartzJobBean;
import com.demo.service.AsdfService;
public class BaseQuartzJobBean extends QuartzJobBean {
@Autowired
private AsdfService asdfService;
@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
System.out.println(" 每3分钟定时器执行,,,demo");
asdfService.findAsdf();
}
}
我们使用继承QuartzJobBean这样 当BaseQuartzJobBean注入其他的Service可能会注入失败 ,这是解决的方式:
package com.demo.qz;
import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.scheduling.quartz.AdaptableJobFactory;
public class BsQuartzJobFactory extends AdaptableJobFactory {
@Autowired
private AutowireCapableBeanFactory capableBeanFactory;
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
//调用父类的方法
Object jobInstance = super.createJobInstance(bundle);
//进行注入,这属于Spring的技术,不清楚的可以查看Spring的API.
capableBeanFactory.autowireBean(jobInstance);
return jobInstance;
}
}