Java 三大器之监听器Listener

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/chenbetter1996/article/details/82831536

监听器需求原因:

       有时候希望不需要用户发起请求而后台定时处理某种事务。如签到功能模块,每天凌晨00:00自动将用户数据库的所有签到状态自动更新为未签到,这是不需要用户发请求的,是后台自动定时触发处理的。

       

实现方法:

       定义一个 extends HttpServlet implements ServletContextListener 的监听类

package io.bbc13.controller;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import io.bbc13.service.DateTimerTask;
import io.bbc13.service.WeekTimerTask;

/**
 * @Lin
 * @每天每周定时任务监听器
 * @每天凌晨零点更新签到状态为非
 * @每周日凌晨零点更新矿工数-10
 */
public class TimeContextListener extends HttpServlet implements ServletContextListener {
	private ServletContext context = null;

	/* 监听开始销毁 */ 
	public void contextDestroyed(ServletContextEvent sce) {
		this.context.log("定时器销毁");
	}
	 
	/* 监听开始执行 */
    public void contextInitialized(ServletContextEvent sce) {
    	this.context= sce.getServletContext();

    	this.context.log("定时器开始");
    	// 当监听开始执行时,设置一个TIME
    	Timer timer = new Timer(true);   // 是否为守护进程danemon
    	
    	// 获取当前时间到00:00:00(24:00:00)的时间差
    	SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
		String now = sdf.format(new Date());
		long gap = 0;
		try {
			Date toM = sdf.parse("24:00:00");  
			Date fromM = sdf.parse(now);  
			long from = fromM.getTime();  
			long to = toM.getTime();  
			gap = to - from;
			System.out.println("距离24:00:00时间差 " + gap + "ms");
		} catch(Exception e) {
			e.printStackTrace();
		}
    	
    	System.out.println("-------DateTimerTask开始进行执行--------------");
    	
    	// 定时任务
 	    DateTimerTask dtt = new DateTimerTask(this.context);  
 	    WeekTimerTask wtt = new WeekTimerTask(this.context);
 	    
 	    // 开始执行dtt对象的,第二参数为开始时间,第三个参数为间隔时间,单位毫秒
 	    timer.schedule(dtt, gap, 24 * 60 * 60 * 1000);     // 定时每天的更新签到
 	    timer.schedule(wtt, gap, 7 * 24 * 60 * 60 * 1000);   // 定时每周日的减矿工
 	    
 	    System.out.println("-------DateTimerTask已经在执行--------------");
    }
}

ServletContextListener所属的线程会在容器启动时就开始执行,一直不中断。

利用其特性和结合TimerTask(一个对象创建一条线程)定时任务类, 可以实现。

package io.bbc13.service;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimerTask;

import javax.servlet.ServletContext;

import org.apache.ibatis.session.SqlSession;

import io.bbc13.util.MybatisUtil;

public class DateTimerTask extends TimerTask {
	private ServletContext context = null; 

	public DateTimerTask(ServletContext context) {
		this.context = context;
	}
	

	/* 执行对象的任务函数 */
	@Override
	public void run() {
		String now = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
		System.out.println("service.DateTimeTask" + now + " 被执行了 DateTimerTask");
		
		// 开始每天签到更新操作
		
	}

}

任务类继承TimerTask抽象类,重写run方法即可。

监听器注册:

和Servlet等注册一样,在web.xml中(按首字母排序)

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>bobo</display-name>
  
  <!-- 注册过滤器 -->
 
  
  <!-- 注册监听器 -->
  <listener>
     <listener-class>io.bbc13.controller.TimeContextListener</listener-class>
  </listener>
  
  <!-- 注册servlet -->
  
  
</web-app>

猜你喜欢

转载自blog.csdn.net/chenbetter1996/article/details/82831536