Spring Session + Redis 实现session共享

关于Spring Session + Redis实现session共享的问题网上有很多案例,但是尝试好久最终都没有解决问题,建议大家还是去官网看一下,如何实现https://docs.spring.io/spring-session/docs/1.3.0.RELEASE/reference/html5/#httpsession-redis

官网提供了两种方式:1.Java Based Configuration基于Java的配置;2.XML Based Configuration基于XML的配置。如下图黄色区域:

这里主要介绍一下基于xml的配置:

1. pom.xml文件中引入所需依赖

<!-- spring-session begin-->
    <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-redis</artifactId>
        <version>1.7.6.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.session</groupId>
        <artifactId>spring-session</artifactId>
        <version>1.3.0.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
        <version>2.8.1</version>
    </dependency>

2.Redis配置文件中配置以下信息(注:官网中说配置LettuceConnectionFactory信息,或者其他文档中说配置JedisConnectionFactory信息,都是一个意思,其实LettuceConnectionFactoryJedisConnectionFactory都实现了RedisConnectionFactory接口,具体查看https://www.2cto.com/kf/201705/638410.html):

        <bean id="connectionFactory"
		    class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
		p:host-name="${redis.host}" p:port="${redis.port}" p:password="${redis.pass}"
		p:pool-config-ref="poolConfig" p:database="14"/>
	<bean id="redisHttpSessionConfiguration"
		  class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration">
		<property name="maxInactiveIntervalInSeconds" value="9999999" />
	</bean>

通过官网上“We use the combination of <context:annotation-config/> and RedisHttpSessionConfiguration because Spring Session does not yet provide XML Namespace support (see gh-104). This creates a Spring Bean with the name of springSessionRepositoryFilter that implements Filter. The filter is what is in charge of replacing the HttpSession implementation to be backed by Spring Session. In this instance Spring Session is backed by Redis.”这段话可知,RedisHttpSessionConfiguration的id必须是redisHttpSessionConfiguration

3.其他地方大多数都是在web.xml中配置过滤器,如下配置:

<!-- spring-session -->
<filter>
    <filter-name>springSessionRepositoryFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
    <filter-name>springSessionRepositoryFilter</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>ERROR</dispatcher>
</filter-mapping>

在这是通过java配置过滤器,只要继承org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer抽象类即可,在这个类中会自动装配。重写beforeSessionRepositoryFilter方法和afterSessionRepositoryFilter方法。

beforeSessionRepositoryFilter方法,加载的是必要信息;afterSessionRepositoryFilter方法添加一些自己配置的过滤器。

    @Override
    protected void beforeSessionRepositoryFilter(ServletContext servletContext) {
        // Create the dispatcher servlet's Spring application context
        AnnotationConfigWebApplicationContext dispatcherServlet = new AnnotationConfigWebApplicationContext();
        dispatcherServlet.register(MvcConfig.class);
        dispatcherServlet.setServletContext(servletContext);
        servletContext.addListener(new ContextLoaderListener(dispatcherServlet));
        dispatcherServlet.scan("com.qxs.web.config.MvcConfig");

	ServletRegistration.Dynamic registration = servletContext.addServlet("dispatcher", new DispatcherServlet(dispatcherServlet));
        registration.setLoadOnStartup(1);
        registration.addMapping("/");
    }
    @Override
    protected void afterSessionRepositoryFilter(ServletContext servletContext) {
        DelegatingFilterProxy delegatingFilterProxy = new DelegatingFilterProxy();
        servletContext.addFilter("shiroFilter", delegatingFilterProxy)
		 .addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), false, "/*");

        //add UTF-8 filter
        final CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
        characterEncodingFilter.setEncoding("UTF-8");
        characterEncodingFilter.setForceEncoding(false);
        servletContext.addFilter("characterEncodingFilter", characterEncodingFilter)
        			 .addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), false, "/*");

        //Todo - add SiteMeshFilter

        SiteMeshFilter siteMeshFilter = new SiteMeshFilter();
        servletContext.addFilter("siteMeshFilter", siteMeshFilter)
		 .addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), false, "/*");

        OpenEntityManagerInViewFilter openEntityManagerInViewFilter = new OpenEntityManagerInViewFilter();
        openEntityManagerInViewFilter.setEntityManagerFactoryBeanName("entityManagerFactory");
        servletContext.addFilter("openEntityManagerInViewFilter", openEntityManagerInViewFilter)
		 .addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), false, "/*");
    }

4.在启动的过程中会运行AbstractHttpSessionApplicationInitializer的onStartup(ServletContext sevletContext)方法,调用insertSessionRepositoryFilter方法,然后装配springSessionRepositoryFilter过滤器。

至此,Spring Session + Redis 实现共享session就结束了。













猜你喜欢

转载自blog.csdn.net/crazy__qu/article/details/79788670