springsessionredis的简单介绍
本篇文章给大家谈谈springsessionredis,以及对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。
本文目录一览:
- 1、SpringBoot整合SpringSeesion实现Redis缓存
- 2、spring boot + redis 实现session共享分析
- 3、如何使用Spring Session实现分布式Session管理
SpringBoot整合SpringSeesion实现Redis缓存
使用Spring Boot开发项目时我们经常需要存储Session,因为Session中会存一些用户信息或者登录信息。传统的web服务是将session存储在内存中的,一旦服务挂了,session也就消失了,这时候我们就需要将session存储起来,而Redis就是用来缓存seesion的一种非关系型数据库,我们可以通过配置或者注解的方式将Spring Boot和Redis整合。而在分布式系统中又会涉及到session共享的问题,多个服务同时部署时session需要共享,迟昌Spring Session可以帮助我们实现这一功能。将Spring Session集成到Spring Boot框架中并使用Redis进行缓存是目前非常流行的解决方案,接下来就跟着我一起学习吧。
工具/材料
IntelliJ IDEA
首先我们创建一个Spring Boot 2.x的项目,在application.properties配置文件中添加Redis的配置,Spring和Redis的整合可以参考我其他的文章,此处不再详解。我们设置服务端口server.port为8080端口用于启动第一个服务。
接下来我们需要在pom文件中添加spring-boot-starter-data-redis和spring-session-data-redis这两个依赖,spring-boot-starter-data-redis用于整合Spring Boot和Redis,spring-session-data-redis集成了spring-session和spring-data-redis,提供了session与redis的整合方案。
接下来我们创建一个配置类RedisSessionConfig,这个类使用@Configuration注解表明这是一个配置类。在这个类上我们同时添加注解@EnableRedisHttpSession,表示开启Redis的Session管理差旦老。如果需要设置失效时间可以使用@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 3600)表示一小时后失效。若同时需要设置Redis的命名空间则使用@EnableRedisHttpSession(maxInactiveIntervalInSeconds=3600, redisNamespace="{spring.session.redis.namespace}") ,其中{spring.session.redis.namespace}表示从配置文件中读取这个命名空间。
配置完成后我们写一个测试类SessionController,在这个类中我们写两个方法,一个方法用于往session中存数据,一个用于从session中取数据,代码如下图所示,我们存取请求的url。启动类非常简单,一般都是通用的,我们创建一个名为SpringbootApplication的启动类,使用main方法启动。
接下来我们使用Postman分别请求上面两个接口,先请求存数据接口,再请求取数据接口,结果如下图所示,我们可以看到数据已从redis中取出。另外需要注意sessionId的值,这是session共享的关键。
为了验证两个服务是否共享了session,我们修改项目的配置文件,将服务端口server.port改为8090,然后再启动服务。此时我们不必在请求存数据的接口,只需要修改请求端口号再一次请求取数据的接口即可。由下图可以看到两次请求的sessionId值相同,实现了session的共享。
以上我们完成了SpringBoot整合SpringSeesion实现Redis缓存的功能,在此我们还要推荐一个Redis的可视化工具RedisDesktopManager,我们可以配置Redis数据库的连接,然后便可以非常直观地查看到虚升存储到Redis中的session了,如下图所示,session的命名空间是share,正是从配置文件中读取到的。
特别提示
如果Redis服务器是很多项目共用的,非常建议配置命名空间,否则同时打开多个项目的浏览器页面可能会导致session错乱的现象。
[img]spring boot + redis 实现session共享分析
HttpSession是由servelet容器进行管理的。而我们常用的应用容器有 Tomcat/Jetty等, 这些容器的HttpSession都是存放在对应的应用容器的岩弯内存中,在分布式集群的环境下,通常我们使用Nginx或者LVS、Zuul等进行反向代理和负载均衡,因此用户请求是由一组提供相同服务的应用来进行处理,而用户最终请求到的服务由Nginx和LVS、Zuul进行确定。
那么问题就来了,我们怎样保证多个相同的应用共享同一份session数据?对于这种问题Spring为我们提供了Spring Session进行管理我们的HttpSession。项目地址:
1.添加Spring session的包,而Spring session 是将HttpSession存放在Redis中,因此启唯需要添加Redis的包。我们这里是用了悄枣培Spring boot进行配置Rdies。
2.使用@EnableRedisHttpSession注解进行配置启用使用Spring session。
3.配置我们的Redis链接,我们这里使用的是Spring Boot作为基础进行配置,因此我们只需要在YML或者Properties配置文件添加Redis的配置即可。
4.创建请求的控制器来进行确定我们是否启用Session 共享。
5.将当前的工程拷贝一份.
通过上面请求显示的结果我们可以看出使用的是同一个Seesion,我们也可以查看下存在Redis中的Session。我这里使用RDM进行查看,我们还可以查看Session的属性。从图可以看出我们存进入的url属性。
我们从启动Spring Session的配置注解@EnableRedisHttpSession开始。
1.我们可以通过@EnableRedisHttpSession可以知道,Spring Session是通过RedisHttpSessionConfiguration类进行配置的。
2.我们在RedisHttpSessionConfiguration类种的注释可以知道,该类是用于创建一个过滤SessionRepositoryFilter。
3.探究下SessionRepositoryFilter类是在哪里创建\创建过程\作用。
(1)哪里创建:
通过搜索RedisHttpSessionConfiguration发现SessionRepositoryFilter的创建不是在RedisHttpSessionConfiguration,而是在父类SpringHttpSessionConfiguration中创建。
(2)SessionRepositoryFilter创建过程:
这里我们可以总结下:
Redis确保链接的情况下。
1.创建sessionRedisTemplate
2.创建RedisOperationsSessionRepository
3.创建SessionRepositoryFilter
(3)SessionRepositoryFilter的作用:
SessionRepositoryFilter的主要作用接管Seession的管理。我们可以从下面几个点知道为什么?
4.我们研究下SessionRepositoryRequestWrapper是怎样接管Session?
(1)存储Session的过程
当调用SessionRepositoryFilter.this.sessionRepository.save(session)完毕后,会判断当前的SessionId是否与请求的中的Cookie中SessionId一致,若不一致的情况下会调用onNewSession()方法,我们可以通过SpringHttpSessionConfiguration配置类的可以看到使用的是
CookieHttpSessionStrategy();
从CookieHttpSessionStrategy.onNewSession()方法可以看到是将SessionId写到Cookie中。
(2)获取Session的过程
我们根据源码的分析可以知道:
1.Spring Session 是通过SessionRepositoryFilter过滤器进行拦截,然后通过SessionRepositoryRequestWrapper继承HttpServletRequestWrapper进行管理Session。
2.Spring Session 为我们提供了3中存放的策略而每种策略提供对应的注解启动。分别为:
(1)NoSql形式的MongoDb:@EnableMongoHttpSession
(2)持久化形式的JDBC:@EnableJdbcHttpSession
(3)缓存形式的Redis:@EnableRedisHttpSession
3.Spring Session 共享Session过程:
(1)先过程过滤器存储将SessionID存放到本地的Cookie 和Redis中。
如果本地没有启用Cookie的情况下,Spring Session也就不能使用。
(2)获取Session的时候,先从请求中获取Session,Session不为空的情况下直接返回Session,若当前的Session为空的情况下,从Cookie中获取SessionId,判断SessionId不为空,再从Redis中获取Session,若从Redis中获取到的Session不为空将Session存放到请求中,再返回Session,如果从Redis中获取的Session为空,再创建新的Session并且添加到请求中,后返回Session。
如何使用Spring Session实现分布式Session管理
Spring Session作为Spring社区官方推荐的一个比较简单快速则启的Java Web分布式session解决方案,帮我们搞定了长期以来比较蛋疼的session分布式的问题。
Spring Session解决的基本思路很简单,即将用户的session信息缓改全部存放到一个redis数据库中,所有的session都从这个数据库拿。由于redis是一个内存数据库,数据信息读写是非常快速的。如此一来,多个Tomcat,共用一个redis数据孙哪如库,即实现了session的共享问题。
访问Spring Session官方网站:
在百度中查询Spring Session即可找到Spring Session的官方站点。
目前版本为1.0.2,1.0.3版本处于snapshot状态。
Spring指出,Spring Session具有如下能力:
(1) API and implementations for managing a user's session
(2) HttpSession - allows replacing the HttpSession in an application container (i.e. Tomcat) neutral way
(2-1)Clustered Sessions - Spring Session makes it trivial to support clustered sessions without being tied to an application container specific solution.
(2-2)Multiple Browser Sessions - Spring Session supports managing multiple users' sessions in a single browser instance (i.e. multiple authenticated accounts similar to Google).
(2-3)RESTful APIs - Spring Session allows providing session ids in headers to work with RESTful APIs
(3) WebSocket - provides the ability to keep the HttpSession alive when receiving WebSocket messages
对Spring Session有了基本了解之后,可以开始配置Maven的pom.xml,导入SpringSession的jar包
Spring官方文档指出,要使用Spring Session,配置如下依赖即可:
dependency
groupIdorg.springframework.session/groupId
artifactIdspring-session-data-redis/artifactId
version1.0.2.RELEASE/version
/dependency
实际上,spring-session-data-redis并不是一个实际的jar包,只不过它配置了其他的四个依赖:
Spring-session-data-redis是一个空的包,我们可以从如下截图中看出。Spring-session-data-redis仅仅只有一个META-INF文件夹。它的作用就在于引入其他四个包。
当然,实际上你也可以不配置spring-session-data-redis,而直接配置实际上导入的类:
!-- Redis --
dependency
groupIdorg.springframework.data/groupId
artifactIdspring-data-redis/artifactId
version1.4.2.RELEASE/version
/dependency
dependency
groupIdredis.clients/groupId
artifactIdjedis/artifactId
version2.5.2/version
/dependency
!-- Spring Session --
dependency
groupIdorg.springframework.session/groupId
artifactIdspring-session/artifactId
version1.0.2.RELEASE/version
/dependency
dependency
groupIdorg.apache.commons/groupId
artifactIdcommons-pool2/artifactId
version2.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数据库。
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查看依赖情况:
此外,注意javax.servlet-api需要3.0.1版本以上。
配置application-context.xml文件
这里,我们以使用xml配置方式为例,当然也可以使用注解配置,详见SPring的官方例子(见参考资料)
备注:xml的配置方法官方给出了一个例子:
在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文件中即可。
修改web.xml,加入Spring Session的Filter
在web.xml文件中,加入:
filter
filter-namespringSessionRepositoryFilter/filter-name
filter-classorg.springframework.web.filter.DelegatingFilterProxy/filter-class
/filter
filter-mapping
filter-namespringSessionRepositoryFilter/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数据库中。
访问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
关于springsessionredis和的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。