
由于项目需求:每隔一段时间就要调外部接口去进行某些操作,于是在网上找了一些资料,用了半天时间弄好了,代码:
import java.util.TimerTask; public class AccountTask extends TimerTask { @Override
public void run() {
System.out.prinln("开始执行定时任务业务");
}
}
import java.util.Timer; import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener; public class AccountTimerListener implements ServletContextListener { private Timer timer = null; @Override
public void contextInitialized(ServletContextEvent event) {
timer = new Timer(true);
event.getServletContext().log("定时器已启动");
// 服务器启动后,延迟7秒启动,5秒执行一次
timer.scheduleAtFixedRate(new AccountTask(), 7 * 1000, 5 * 1000);
} @Override
public void contextDestroyed(ServletContextEvent event) {
if (timer != null) {
timer.cancel();
event.getServletContext().log("定时器销毁");
}
}
}
然后在web.xml文件中配置监听
<listener>
<listener-class>com.xxx.AccountTimerListener</listener-class>
</listener>
启动之后,会发现没隔5秒打印一次: 开始执行定时任务业务 。
然而,当调度类中调用service层业务时,启动tomcat后,执行定时任务时会报空指针异常,这是由于这个定时任务目前只是一个普通的类,我们需要将这个定时任务注入到spring中,监听。
解决方案如下:
package com.test.utils; import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener; import org.springframework.context.ApplicationContext;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils; public class SpringInit implements ServletContextListener { private static WebApplicationContext springContext; public SpringInit() {
super();
} @Override
public void contextDestroyed(ServletContextEvent event) {
// TODO Auto-generated method stub
} @Override
public void contextInitialized(ServletContextEvent event) {
springContext = WebApplicationContextUtils.getWebApplicationContext(event.getServletContext());
} public static ApplicationContext getApplicationContext() {
return springContext; } }
web.xml文件:
<!-- SpringInit类所在的包 -->
<context:component-scan base-package="com.test.utils" /> <listener>
<listener-class>com.test.utils.SpringInit</listener-class>
</listener>
若 context:component-scan 出报错,可能是因为没有引入标签。
在xmlns:xsi 里加上
http://www.springmodules.org/schema/cache/springmodules-cache.xsd http://www.springmodules.org/schema/cache/springmodules-ehcache.xsd
xsi:schemaLocation里加上
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层业务进行定时任务了。