项目中使用 Spring-session 这个分布式 session 作为负载均衡的 session 中间件,以便统一 session 的管理。

然后我们自己添加了一个 HttpSessionListener, 但是发现它执行了 2 次,实在是太诡异了。(其实是太菜了)

首先项目里的配置大概如下:


    <bean class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration"/>
    <bean id="l" class="org.springframework.session.web.http.SessionEventHttpSessionListenerAdapter">
            <constructor-arg>
                <list>
                    <ref bean="webHttpSessionListener" />
                </list>
            </constructor-arg>
    </bean>
    <bean class="org.springframework.security.web.session.HttpSessionEventPublisher"/>

定位问题

这个之前是看了下 SpringSecurity 项目中大概的配置的,使用 SessionEventHttpSessionListenerAdapter 来添加HttpSessionListener,那就怀疑是这里出了问题。所以打开该类的源码,定位到相应的初始化 listeners 的方法。

发现它初始化了 2 次!

第一次: img

第二次: img

原因


 <bean class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration"/>

再通过详细查看资料,发现 Spring-session 这个类是进行自动配置的(spring-boot 风格),所以不用再显式添加下面的 listener 这些配置了的。

所以,直接注释掉这段代码即可:

```bash

<bean id="l" class="org.springframework.session.web.http.SessionEventHttpSessionListenerAdapter">
        <constructor-arg>
            <list>
                <ref bean="webHttpSessionListener" />
            </list>
        </constructor-arg>
</bean>
<bean class="org.springframework.security.web.session.HttpSessionEventPublisher"/>

````

实现监听器 HttpSessionListener

自定义的类,实现了该接口,并且注册到 Spring 容器,那么它就会自动添加到 SessionListener 容器里的,就不用再进行其他额外的配置了。看来,以前看的文档还不够详细,只是匆匆忙忙赶着能用的态度。没有注意到该 listener 被注册了多次的问题!