最近用做的项目不大,但是涉及到的技术挺多,对于我来说也比较新。定时器也是第一次用到,虽然没有用Spring的定时器,不过这个也还不错:
简单来说创建一个定时任务分为三部分:
1、时间监听器: 用于监听时间,决定任务的执行周期。利用java.util.Timer执行;
主要用到了Timer中的两个方法timer.schedule(new yourTask(), 0,1000)——开启任务,timer.cancel()——销毁定时器
时间监听器需要继承ServletContextListenter,用于监听ServletContext的生命周期(web的生命周期)。详解http://blog.csdn.net/zhaozheng7758/article/details/6103700
至于HttpServlet,则首先用于接收和读取Http请求,采用HTTP协议,而且一次任务的请求也是一次http请求,因此要继承HttpServlet抽象类。忘记HttpServlet原理的童鞋们可以参阅一下:http://my.oschina.net/wmy1988/blog/75201
public class TaskListener extends HttpServlet implements ServletContextListener { private static final long serialVersionUID = 1L; private Timer timer = null; @Override public void contextDestroyed(ServletContextEvent event) { timer.cancel();//销毁定时器,这是必须的,每次开启了都要在此次任务执行结束时关闭 event.getServletContext().log("执行分析定时器销毁"); } @Override public void contextInitialized(ServletContextEvent event) { timer = new Timer(true); event.getServletContext().log("执行分析定时器已经启动"); timer.schedule(new TimeTaskWork(event.getServletContext()), 0,1000); // 0表示tomcat启动的时候运行切不延迟,1000表示运行周期为1秒 event.getServletContext().log("已经存在任务调度列表"); } }
2、任务执行:包括定时器在运行的这段期间要做的事情,利用java.util.TimerTask;
我的定时任务比较复杂,不过过程中也发现了不少问题:
(1). 我整个项目都是用的注解,因此在写定时器时用@Inject来实例化对象,但是运行时会报taskBarcodeService空指针异常,然后将接口通过new对象来实例化,就没有了此错误。
(2). 在run()方法中定义的对象如Sample sample = new Sample(); 此对象也会报空指针异常,必须将此对象定义为“成员变量”。
public class TimeTaskWork extends TimerTask { @Inject //注解无效 private final TaskBarcodeService taskBarcodeService = new TaskBarcodeServiceImpl();private ServletContext context = null;private final Sample sample = new Sample(); public TimeTaskWork(ServletContext context) { this.context = context; //实例化时将任务中的日志与监听器中的日志同步 } @Override public void run() { System.out.println("-------------in task----------------");
...... } }
3、web.xml中配置监听器(一开始没有在web.xml中配置,直接在java程序中调用了,结果每次调用都启用一个定时任务,占用了很大内存空间);
<listener> <listener-class>com.nova.lims.task.TaskListener</listener-class> </listener>