1. 程式人生 > >Spring Session + Redis 實現session共享

Spring Session + Redis 實現session共享

這裡主要介紹一下基於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就結束了。