如何使用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

但愿你们多多讨论,互相学习~

相关文章
相关标签/搜索