spring定时任务
需求:在tomcat启动时开启一个定时任务,即项目启动完成后,自动执行某一特定任务。
想法:容器启动时执行方法,最容易想到的就是servlet中可以配置load-on-startup,设置一个正整数也就可以随容器一起启动。
问题:上面的方法很好,但是由于定时任务需要去操作数据库,而项目采用了spring的依赖注入来管理对象,而servlet并不受Spring的管理。若此时在servlet中注入Spring管理的对象,则会报错:javax.naming.NameNotFoundException: Name com.test.InitServlet is not bound in this Context。所以想要再servlet中操作数据库,只能手动去创建一个service(new ...),这显然违背了我们使用Spring的初衷,让项目看起来不伦不类的。那么如何才能在启动WEB容器的时候执行一段初始化代码,并且可以让其被Spring管理呢?
解决方案:Spring对Timer的支持的核心是由ScheduledTimerTask和TimerFactoryBean类组成的。 ScheduledTimerTask类是对TimerTask的包装器实现,这样你就可以为这个任务定义触发器信息。使用 TimerFactoryBean类,你可以让Spring使用配置创建触发器,并为一组指定的ScheduledTimerTask bean自动创建Timer实例。
看一个简单实例:
applicationContext.xml
1 <!--自定义任务--> 2 <bean id="mqttTask" class="com.bsit.device.struts.task.MQTT_Task"/> 3 <!-- 设置任务属性 --> 4 <bean id="scheduledTask" class="org.springframework.scheduling.timer.ScheduledTimerTask"> 5 <property name="timerTask"> 6 <ref bean="mqttTask"/> 7 </property> 8 <!-- 任务执行周期 2s,2s执行一次--> 9 <!-- <property name="period"> 10 <value>2000</value> 11 </property> --> 12 <!-- 延时3m 执行任务 --> 13 <property name="delay"> 14 <value>3000</value> 15 </property> 16 </bean> 17 <!-- 启动定时器 --> 18 <bean id="timerBean" class="org.springframework.scheduling.timer.TimerFactoryBean"> 19 <property name="scheduledTimerTasks"> 20 <list> 21 <ref bean="scheduledTask"/> 22 </list> 23 </property> 24 </bean>
MQTT_Task:
1 public class MQTT_Task extends TimerTask{ 2 3 private OrgService orgService; 4 5 @Override 6 public void run() { 7 System.out.println("......hello......"); 8 List<Org> orgList = orgService.listAll("Org"); 9 System.out.println(" orgList's size is " + orgList.size()); 10 System.out.println("......word......"); 11 } 12 13 public void setOrgService(OrgService orgService){ 14 this.orgService = orgService; 15 } 16 }
查看控制台:
1 ......hello...... 2 orgList's size is 24 3 ......word......
在项目启动完3s之后,自动执行该定时任务,且spring配置均已加载完毕,这时可以使用service,符合使用Spring的初衷。
使用Java中的定时器比较简单,其提供的任务也比较简单,如果定时任务相对复杂,则可采用Quartz框架来配置定时任务。