Spring框架提供了TaskExcutor的異步執行和TashScheduler的任務定時執行接口,同樣spring也提供了線程池或者CommonJ的代理。
TaskExecutor的類型
SimpleAsyncTaskExecutor,沒有復用線程,當觸發時僅僅啟動一個新的線程。支持並發。
SyncTaskExecutor,同步觸發,主要用來不需要多線程的情況,例如測試用例
ConcurrentTaskExecutor,java.util.concurrent.Executor的適配器,作為ThreadPoolTaskExecutor的替代品,很少使用,但如果ThreadPoolTaskExecutor不能滿足你的需求,可以考慮使用它。
SimpleThreadPoolTaskExecutor,Quartz的SimpleThreadPool子類實現,它監聽spring生命周期的callback,主要用來在quartz和非quartz組件共享線程池時。
ThreadPoolTaskExecutor,常用的TaskExecutor實現類。
WorkManagerTaskExecutor,使用了CommJ的WorkMannager作為它的實現,它提供了在spring contxt中建立一個CommonJ WorkManger的便利主類,類似於SimpleThreadPoolTaskExecutor。
注:CommonJ是BEA和IBM開發的
TaskExecutor使用示例:
import org.springframework.core.task.TaskExecutor; public class TaskExecutorExample { private class MessagePrinterTask implements Runnable { private String message; public MessagePrinterTask(String message) { this.message = message; } public void run() { System.out.println(message); } } private TaskExecutor taskExecutor; public TaskExecutorExample(TaskExecutor taskExecutor) { this.taskExecutor = taskExecutor; } public void printMessages() { for(int i = 0; i < 25; i++) { taskExecutor.execute(new MessagePrinterTask("Message" + i)); } } }
配置文件:
<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"> <property name="corePoolSize" value="5" /> <property name="maxPoolSize" value="10" /> <property name="queueCapacity" value="25" /> </bean> <bean id="taskExecutorExample" class="TaskExecutorExample"> <constructor-arg ref="taskExecutor" /> </bean>
使用Quartz Scheduler
1. 使用JobDetailFactoryBean
<bean name="exampleJob" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="jobClass" value="example.ExampleJob"/>
<property name="jobDataAsMap">
<map>
<entry key="timeout" value="5"/>
</map>
</property>
</bean>
測試類
package example; public class ExampleJob extends QuartzJobBean { private int timeout; /** * Setter called after the ExampleJob is instantiated * with the value from the JobDetailFactoryBean (5) */ public void setTimeout(int timeout) { this.timeout = timeout; } protected void executeInternal(JobExecutionContext ctx) throws JobExecutionException { // do the actual work } }
2. 使用MethodInvokingJobDetailFactoryBean
配置文件
<bean id="jobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> <property name="targetObject" ref="exampleBusinessObject"/> <property name="targetMethod" value="doIt"/> </bean>
對應的方法
public class ExampleBusinessObject { // properties and collaborators public void doIt() { // do the actual work } }
<bean id="exampleBusinessObject" class="examples.ExampleBusinessObject"/>
有狀態的job,一個任務沒完成之前,相同任務的下個不會執行
<bean id="jobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> <property name="targetObject" ref="exampleBusinessObject"/> <property name="targetMethod" value="doIt"/> <property name="concurrent" value="false"/> </bean>
3. 使用triggers 和SchedulerFactoryBean包裝job
兩種類型的TriggerFactoryBean,分別是SimpleTriggerFactoryBean和CronTriggerFactoryBean
<bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean"> <!-- see the example of method invoking job above --> <property name="jobDetail" ref="jobDetail"/> <!-- 10 seconds --> <property name="startDelay" value="10000"/> <!-- repeat every 50 seconds --> <property name="repeatInterval" value="50000"/> </bean> <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <property name="jobDetail" ref="exampleJob"/> <!-- run every morning at 6 AM --> <property name="cronExpression" value="0 0 6 * * ?"/> </bean>
建立SchedulerFactoryBean
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="triggers"> <list> <ref bean="cronTrigger"/> <ref bean="simpleTrigger"/> </list> </property> </bean>
參考文獻:
【1】http://docs.spring.io/spring/docs/current/spring-framework-reference/html/scheduling.html
【2】http://www.cnblogs.com/davidwang456/p/4237895.html
