当前位置:首页 > 开发 > 系统架构 > 架构 > 正文

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

发表于: 2012-05-08   作者:Dead_knight   来源:转载   浏览次数:
摘要: 很多spring security3资料在介绍session的并发控制都要求配置HttpSessionEventPublisher的监听器,如下 <listener> <listener-class> org.springframework.security.web.session.HttpSessionEventPublisher
很多spring security3资料在介绍session的并发控制都要求配置HttpSessionEventPublisher的监听器,如下
    <listener>
    	<listener-class>
org.springframework.security.web.session.HttpSessionEventPublisher
         </listener-class>
    </listener>

这个监听器实现了HttpSessionListener接口,主要监听sessionCreated、sessionDestroyed事件。看源码
public class HttpSessionEventPublisher implements HttpSessionListener {
    private static final Log log = LogFactory.getLog(HttpSessionEventPublisher.class);
    ApplicationContext getContext(ServletContext servletContext) {
        return WebApplicationContextUtils.getWebApplicationContext(servletContext);
    }

    public void sessionCreated(HttpSessionEvent event) {
        HttpSessionCreatedEvent e = new HttpSessionCreatedEvent(event.getSession());

        if (log.isDebugEnabled()) {
            log.debug("Publishing event: " + e);
        }
        //通过ApplicationContext的事件发布机制发布sessionCreated事件
        getContext(event.getSession().getServletContext()).publishEvent(e);
    }

    public void sessionDestroyed(HttpSessionEvent event) {
        HttpSessionDestroyedEvent e = new HttpSessionDestroyedEvent(event.getSession());

        if (log.isDebugEnabled()) {
            log.debug("Publishing event: " + e);
        }
        //通过ApplicationContext的事件发布机制发布sessionDestroyed事件
        getContext(event.getSession().getServletContext()).publishEvent(e);
    }
}

由于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强制失效。

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

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
前面分析了FilterChainProxy执行过程,也对常用的filter逐一深入介绍了,但似乎忽略了Spring Securi
前面分析了FilterChainProxy执行过程,也对常用的filter逐一深入介绍了,但似乎忽略了Spring Securi
前面分析了FilterChainProxy执行过程,也对常用的filter逐一深入介绍了,但似乎忽略了Spring Securi
前面分析了FilterChainProxy执行过程,也对常用的filter逐一深入介绍了,但似乎忽略了Spring Securi
前面分析了FilterChainProxy执行过程,也对常用的filter逐一深入介绍了,但似乎忽略了Spring Securi
0 概述 spring-web的web模块是更高一层的抽象,它封装了快速开发spring-web需要的基础组件。其结构
Spring 是一个非常流行和成功的 Java 应用开发框架。Spring Security 基于 Spring 框架,提供了一套
一、Spring核心类概述。 Spring里面有两个最核心的类这是Spring实现最重要的部分。 1、DefaultLista
资源信息(文件、url响应的信息。。)对开发是很重要的东西。jdk也提供了访问资源的一些基类(File
本篇文章将会介绍上一个例子中的源码执行情况,从中熟悉整个SpringAOP的一些概念和接口设计。 首先
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号