首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

Spring Security3源码分析-SessionManagementFilter分析-停

2012-08-03 
Spring Security3源码分析-SessionManagementFilter分析-下很多spring security3资料在介绍session的并发

Spring Security3源码分析-SessionManagementFilter分析-下
很多spring security3资料在介绍session的并发控制都要求配置HttpSessionEventPublisher的监听器,如下


由于ApplicationContext继承了ApplicationEventPublisher接口,所以ApplicationContext具有发布事件的能力。
Spring中与事件有关的接口和类主要包括ApplicationEvent、ApplicationListener。
定义一个事件的类需要继承ApplicationEvent或者ApplicationContextEvent抽象类。针对一种事件,需要特定的监听器,监听器需要实现ApplicationListener接口。当监听器接收到一个事件的时候,就会执行它的 onApplicationEvent()方法。

上面的代码仅仅发布了session事件,针对session事件,谁去监听并处理呢?
spring security中监听session事件的类是SessionRegistryImpl(org.springframework.security.core.session.SessionRegistryImpl)
这个类实现了ApplicationListener<SessionDestroyedEvent>接口,但是这个类在哪里注册到ioc容器中的呢。
如果看完上一篇的分析,应该知道是解析标签concurrency-control时创建这个bean并注册到ioc容器的。如果没有配置这个标签,这个类的bean就不会产生。

接着看SessionRegistryImpl类中的处理事件的方法onApplicationEvent
    //实际上SessionRegistryImpl仅仅处理SessionDestroyedEvent    //接收到session失效事件,从当前缓存中清除SessionInformation    public void onApplicationEvent(SessionDestroyedEvent event) {        String sessionId = event.getId();        removeSessionInformation(sessionId);    }    //根据失效的sessionid清除SessionInformation对象    public void removeSessionInformation(String sessionId) {        Assert.hasText(sessionId, "SessionId required as per interface contract");        SessionInformation info = getSessionInformation(sessionId);        if (info == null) {            return;        }        //从sessionIds中清除SessionInformation        sessionIds.remove(sessionId);        Set<String> sessionsUsedByPrincipal = principals.get(info.getPrincipal());        if (sessionsUsedByPrincipal == null) {            return;        }        //从principals清除SessionInformation对应的认证实体信息        synchronized (sessionsUsedByPrincipal) {            sessionsUsedByPrincipal.remove(sessionId);            if (sessionsUsedByPrincipal.size() == 0) {                principals.remove(info.getPrincipal());            }        }    }


现在,HttpSessionEventPublisher监听器的目的就很明显了。这个过滤器首先监听session失效的事件(web容器配置的timeout、直接调用session.invalidate方法),然后由SessionRegistryImpl处理session失效事件,从自己维护的集合缓存中清除已经失效的session信息以及session对应的认证实体信息,避免造成oom。

这里要重点区分下,上一篇分析的ConcurrentSessionFilter过滤器也是处理session失效,但是它所处理的仅仅封装后的SessionInformation类,如果这个类满足失效条件,再执行session.invalidate强制失效。

热点排行