由於項目需求:每隔一段時間就要調外部接口去進行某些操作,於是在網上找了一些資料,用了半天時間弄好了,代碼:
1 import java.util.TimerTask; 2 3 public class AccountTask extends TimerTask { 4 5 @Override 6 public void run() { 7 System.out.prinln("開始執行定時任務業務"); 8 } 9 }
1 import java.util.Timer; 2 3 import javax.servlet.ServletContextEvent; 4 import javax.servlet.ServletContextListener; 5 6 public class AccountTimerListener implements ServletContextListener { 7 8 private Timer timer = null; 9 10 @Override 11 public void contextInitialized(ServletContextEvent event) { 12 timer = new Timer(true); 13 event.getServletContext().log("定時器已啟動"); 14 // 服務器啟動后,延遲7秒啟動,5秒執行一次 15 timer.scheduleAtFixedRate(new AccountTask(), 7 * 1000, 5 * 1000); 16 } 17 18 @Override 19 public void contextDestroyed(ServletContextEvent event) { 20 if (timer != null) { 21 timer.cancel(); 22 event.getServletContext().log("定時器銷毀"); 23 } 24 } 25 }
然后在web.xml文件中配置監聽
1 <listener> 2 <listener-class>com.xxx.AccountTimerListener</listener-class> 3 </listener>
啟動之后,會發現沒隔5秒打印一次: 開始執行定時任務業務 。
然而,當調度類中調用service層業務時,啟動tomcat后,執行定時任務時會報空指針異常,這是由於這個定時任務目前只是一個普通的類,我們需要將這個定時任務注入到spring中,監聽。
解決方案如下:
1 package com.test.utils; 2 3 import javax.servlet.ServletContextEvent; 4 import javax.servlet.ServletContextListener; 5 6 import org.springframework.context.ApplicationContext; 7 import org.springframework.web.context.WebApplicationContext; 8 import org.springframework.web.context.support.WebApplicationContextUtils; 9 10 public class SpringInit implements ServletContextListener { 11 12 private static WebApplicationContext springContext; 13 14 public SpringInit() { 15 super(); 16 } 17 18 @Override 19 public void contextDestroyed(ServletContextEvent event) { 20 // TODO Auto-generated method stub 21 } 22 23 @Override 24 public void contextInitialized(ServletContextEvent event) { 25 springContext = WebApplicationContextUtils.getWebApplicationContext(event.getServletContext()); 26 } 27 28 public static ApplicationContext getApplicationContext() { 29 return springContext; 30 31 } 32 33 }
web.xml文件:
1 <!-- SpringInit類所在的包 --> 2 <context:component-scan base-package="com.test.utils" /> 3 4 5 <listener> 6 <listener-class>com.test.utils.SpringInit</listener-class> 7 </listener>
若 context:component-scan 出報錯,可能是因為沒有引入標簽。
在xmlns:xsi 里加上
1 http://www.springmodules.org/schema/cache/springmodules-cache.xsd http://www.springmodules.org/schema/cache/springmodules-ehcache.xsd
xsi:schemaLocation里加上
1 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
上面的問題解決。
最后,我們掉用service之前,這樣來獲取bean:
DetailService detailService = (DetailService) SpringInit.getApplicationContext().getBean("detailService");
然后就可以掉用service層業務進行定時任務了。
