由于服务器来管理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();
}
}
}
}
}
}