如何使用Spring Session實現分佈式Session管理

Spring Session做爲Spring社區官方推薦的一個比較簡單快速的Java Web分佈式session解決方案,幫咱們搞定了長期以來比較蛋疼的session分佈式的問題。html

Spring Session解決的基本思路很簡單,即將用戶的session信息所有存放到一個redis數據庫中,全部的session都從這個數據庫拿。因爲redis是一個內存數據庫,數據信息讀寫是很是快速的。如此一來,多個Tomcat,共用一個redis數據庫,即實現了session的共享問題。html5

鑑於目前不多看到Spring Session的相關文章,筆者硬着頭皮,詳細介紹一下基本的配置方法和使用方法。java

  1. Spring Session官方網站                     web

Spring Session的官方網站:http://projects.spring.io/spring-session/redis

Spring Session的官方文檔:http://docs.spring.io/spring-session/docs/1.0.2.RELEASE/reference/html5/spring

目前版本爲1.0.2,1.0.3版本處於snapshot狀態。數據庫

Spring指出,Spring Session具備以下能力:apache

  • API and implementations for managing a user's sessionapi

  • HttpSession - allows replacing the HttpSession in an application container (i.e. Tomcat) neutral way服務器

    • Clustered Sessions - Spring Session makes it trivial to support clustered sessions without being tied to an application container specific solution.

    • Multiple Browser Sessions - Spring Session supports managing multiple users' sessions in a single browser instance (i.e. multiple authenticated accounts similar to Google).

    • RESTful APIs - Spring Session allows providing session ids in headers to work with RESTful APIs

  • WebSocket - provides the ability to keep the HttpSession alive when receiving WebSocket messages

2. 配置Maven的pom.xml,導入SpringSession的jar包

Spring官方文檔指出,要使用Spring Session,配置以下依賴便可:

<dependency>        <groupId>org.springframework.session</groupId>         <artifactId>spring-session-data-redis</artifactId>         <version>1.0.2.RELEASE</version> </dependency> 

實際上,spring-session-data-redis並非一個實際的jar包,只不過它配置了其餘的四個依賴:

Spring-session-data-redis是一個空的包:

僅僅只有一個META-INF文件夾。它的做用就在於引入其餘四個包。

實際上,你也能夠不配置spring-session-data-redis,而直接配置實際上導入的類:

<!-- Redis --> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <version>1.4.2.RELEASE</version> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.5.2</version> </dependency> <!-- Spring Session --> <dependency>        <groupId>org.springframework.session</groupId>        <artifactId>spring-session</artifactId>        <version>1.0.2.RELEASE</version> </dependency> <dependency>       <groupId>org.apache.commons</groupId>       <artifactId>commons-pool2</artifactId>       <version>2.2</version> </dependency> 

咱們這裏,首先,配置spring-data-redis和jedis,這樣,就可使用spring-data-redis框架,來實現訪問redis數據庫。

spring-data-redis是spring的一個子項目,和spring-session同樣。spring-session要訪問redis,這裏spring-session依賴spring-data-redis,來實現操做reids數據庫。

3. Spring Core、Spring Web配置4.x版本

固然,Spring Session還須要把Spring Web等常見的Spring包引入。Spring Session 1.0.2依賴Spring的版本爲4.1.6以上,所以,3.x版本的Spring是沒法使用的:

能夠從Maven Repository查看依賴狀況:http://mvnrepository.com/artifact/org.springframework.session/spring-session/1.0.2.RELEASE

此外,注意javax.servlet-api須要3.0.1版本以上。

4. 配置application-context.xml文件

這裏,咱們以使用xml配置方式爲例,固然也可使用註解配置,詳見SPring的官方例子(http://docs.spring.io/spring-session/docs/1.0.2.RELEASE/reference/html5/#samples)

備註:xml的配置方法官方給出了一個例子:http://docs.spring.io/spring-session/docs/1.0.2.RELEASE/reference/html5/guides/httpsession-xml.html

在application-context.xml文件中,加入:

<context:annotation-config/>  <bean class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration"/>   <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig" />     <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"/> 

其中,${redis.host}等即redis數據庫的服務器地址,端口,密碼等信息,放在properties文件中便可。

5. 修改web.xml,加入Spring Session的Filter

在web.xml文件中,加入:

<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>  </filter-mapping> 

這樣,全部的請求,都會被DelegatingFilterProxy處理,實際上,DelegatingFilterProxy會找到springSessionRepositoryFilter,建立它。每一次的請求仍是由springSessionRepositoryFilter來過濾的。

The DelegatingFilterProxy will look up a Bean by the name of springSessionRepositoryFilter and cast it to a Filter. For every request that DelegatingFilterProxy is invoked, the springSessionRepositoryFilter will be invoked. 

這裏,Spring加入了一個Filter,其本質是:對每個請求的request進行了一次封裝。那麼,在Controller裏面拿出的request其實是封裝後的request,

調用request.getSession()的時候,實際上拿到是Spring封裝後的session。這個session則存儲在redis數據庫中。

6. 訪問Web項目,查看session

訪問Web項目,這個時候,使用redis-cli進入redis命令操做界面,在使用keys *能夠查看全部的key:

第一個是當前訪問的用戶的session信息,第二個保存的是過時的時間。

能夠查看session的詳細內容以下:

能夠看出,session對象被序列化後存入。所以,全部放入session的對象,都要實現Serializable接口。好比,我將全部的用戶信息,封裝到一個Authentication對象,那麼

這對象就必須實現Serializable接口:

補充一下:

若是要設置Session的過時時間,一般咱們會在web.xml文件中進行設置:

可是,使用Spring Session託管session後,這裏的設置將會失效。咱們要專門爲Spring Session進行設置:

將application-context.xml,即步驟4中的的RedisHttpSessionConfiguration,設置其maxInactiveIntervalInSeconds屬性便可。注意,maxInactiveIntervalInSeconds的的單位是秒! 以下將設置session爲10分鐘過時!

<bean class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration"> <property name="maxInactiveIntervalInSeconds" value="600"></property> </bean> 

END

但願你們多多討論,互相學習~

相關文章
相關標籤/搜索