由于服务器来管理session摧毁不精准,为了在某个时间内准确的摧毁session我们需要自定义session扫描器,服务器中的所有的session我们需要写一个程序来管理,当发现某一个session一分钟没有人用了,我们就将它摧毁掉,不要服务器来帮我们摧毁了。
思路:我们要管理所有的session,我们需要写一个监听器,当监听到session的创建,就加到我自己的一个容器内,然后开启一个扫描器,扫描一分钟没有用的session就将它摧毁
代码实现如下:
package cn.test.web.listener; import java.util.Collections; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Timer; import java.util.TimerTask; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionListener; public class SessionScanerListener implements HttpSessionListener,ServletContextListener { //创建session的容器创建为线程安全 private List list = Collections.synchronizedList(new LinkedList<HttpSession>()); private Object lock = new Object(); //当web应用启动的时候创建定时器 public void contextInitialized(ServletContextEvent sce) { Timer timer = new Timer(); // 延迟0秒,没隔1分钟执行一次扫描 timer.schedule(new MyTimerTask(list,lock), 0, 1000*1); } public void sessionCreated(HttpSessionEvent se) { HttpSession session = se.getSession();//得到创建的session System.out.println("session被创建了!!"); synchronized (lock) { //锁旗标 list.add(session); //将session加到容器内 } } public void sessionDestroyed(HttpSessionEvent se) { System.out.println("session被销毁了!!"); } public void contextDestroyed(ServletContextEvent sce) { // TODO Auto-generated method stub } } class MyTimerTask extends TimerTask{ private List list; private Object lock; public MyTimerTask(List list,Object lock){ this.list = list; this.lock = lock; } //扫描器执行的任务 @Override public void run() { synchronized (lock) { if(list!=null){ Iterator<HttpSession> it = list.iterator(); //5 while(it.hasNext()){ HttpSession session = it.next(); //当session一分钟没有用时摧毁session if(System.currentTimeMillis()-session.getLastAccessedTime()>1000*60){ it.remove(); session.invalidate(); } } } } } }