Java提供了两种后台任务的方法
异步任务;@Async
当然,使用这两个是有条件的,需要在spring应用的上下文中声明
当然,如果我们是基于java配置的,需要在配置哪里加多EnableScheduling
@EnableScheduling
public class WebAppConfig {
....
}
先看下@Schedule怎么调用再说
public final static long ONE_DAY = 24 * 60 * 60 * 1000;
public final static long ONE_HOUR = 60 * 60 * 1000;
@Scheduled(fixedRate = ONE_DAY)
public void scheduledTask() {
System.out.println(" 我是一个每隔一天就会执行一次的调度任务");
}
@Scheduled(fixedDelay = ONE_HOURS)
public void scheduleTask2() {
System.out.println(" 我是一个执行完后,隔一小时就会执行的任务");
}
@Scheduled(cron = "0 0/1 * * * ? ")
public void ScheduledTask3() {
System.out.println(" 我是一个每隔一分钟就就会执行的任务");
}
需要注意的
关于最后一个,在指定时间执行的任务,里面使用的是Cron表达式
,同时我们看到了两个不一样的面孔fixedDelay
& fixedRate
,前者表示在指定间隔,运行程序,例如这个程序在今晚九点运行程序,跑完这个方法后的一个小时,就会再执行一次,而后者fixedDelay
者是指,这个函数每隔一段时间就会被调用(我们这里设置的是一天),不管这个方法是在运行还是结束了。
我们在serviceImpl类写这些调度任务时候,也需要在这些我们定义的serviceInterface的借口中写多这个接口,要不然会爆 ***—— but not found in any interface(s) for bean JDK proxy. Either pull the method up to an interface or
有时候我们会调用一些特殊的任务,任务会比较耗时,重要的是,我们不管他返回的后果。这时候我们就需要用这类的异步任务啦,调用后就让他去跑,不堵塞主线程,我们继续干别的。
@Async
public void doSomeHeavyBackgroundTask() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
这比我们手动开多一个线程方便多了。
处理这两个外,还有一个和spring整合的第三方库叫Quartz
看了下官网的使用简介,也是挺逗的,现在都习惯用maven,gradle之类来关系这些依赖了,他还叫人下载,也是不知为何,详情点击->
http://quartz-scheduler.org/documentation/quartz-2.2.x/quick-start
估计有可能是因为没再维护了的原因吧,最新版2.2居然是Sep, 2013更新的。。。
居然是停更的,还是简单说下吧
public class MainTest
{
public static void main(String[] args)
{
System.out.println("Test start.");
ApplicationContext context = new
ClassPathXmlApplicationContext("quartz-config.xml");
//如果配置文件中将startQuertz bean的lazy-init设置为false 则不用实例化
//context.getBean("startQuertz");
System.out.print("Test end..");
}
}
接着我们写下配置的xml文件
<beans>
<bean id="quartzJob" class="com.kay.quartz.QuartzJob">bean>
<bean id="jobtask" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject">
<ref bean="quartzJob"/>
property>
<property name="targetMethod">
<value>workvalue>
property>
bean>
<bean id="doTime" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail">
<ref bean="jobtask"/>
property>
<property name="cronExpression">
<value>10,15,20,25,30,35,40,45,50,55 * * * * ?value>
property>
bean>
<bean id="startQuertz" lazy-init="false" autowire="no" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="doTime"/>
list>
property>
bean>
beans>
最后写下在这个配置文件开头写到的具体的任务类
public class QuartzJob
{
public void work(){
System.out.println("Quartz的任务调度!!!");
}
}
整体用起来感觉是没有spring自己的后台任务方便,不过也可以接受,只需要简单的配置就可以使用了。不过Quartz作为一个企业级应用的任务调度框架,还是一个可以的候选项目的。
tips:
1.“Notice that the methods to be scheduled must have void returns and must not expect any arguments. If the method needs to interact with other objects from the Application Context, then those would typically have been provided through dependency injection.”
Excerpt From: Rod Johnson. “Spring Framework Reference Documentation.” iBooks.
2.“Make sure that you are not initializing multiple instances of the same @Scheduled annotation class at runtime, unless you do want to schedule callbacks to each such instance. Related to this, make sure that you do not use @Configurable on bean classes which are annotated with @Scheduled and registered as regular Spring beans with the container: You would get double initialization otherwise, once through the container and once through the @Configurable aspect, with the consequence of each @Scheduled method being invoked twice.”
Excerpt From: Rod Johnson. “Spring Framework Reference Documentation.” iBooks.