SpringSession原理

Session原理

  • 浏览器第一次访问服务器,登录成功后服务器会保存一个session对象(可看成map对象),session对象里以键值对的方式保存了用户的登录信息,并且每一个session对象都会对应一个独特的sessionId
  • 登录成功后服务器会返回一个JsessionId=xxx的Cookie给浏览器,浏览器下次访问时带上这个cookie,服务器就可以根据sessionid判断用户有没有登录。

session共享问题

  • 服务器发回来的cookie默认作用域domain是本服务器域名,例如让认证服务器返回的是auth.gulimall.com,而cookie作用域不同是不能共享的,也就是说auth.gulimall.com的作用域不能作用于gulimall.com。

  • 分布式下session共享问题,对于集群里的服务器(服务有多个相同的),有以下几种解决方案:

  • 使用springSession解决(底层使用redis)(推荐使用) ,对于不同服务下不用域名的问题,使用自定义cookie的作用域domain解决。

  • session复制,让集群中的服务器互相同步session
    优点:web-server(tomcat)原生支持,只需要修改tomcat配置文件即可
    缺点:1. session同步需要传输数据,占用集群之间的网络带宽
    2.任意一台服务器都需要保存所有服务器的session数据,如果session数据量大的话会导致内存浪费严重,内存限制。
    3.客户端存储,把数据存储在浏览器中的cookie里。
    优点:1. 服务器不需要保存session,节省服务器资源
    缺点:1.不安全,存在泄漏、篡改、窃取等安全问题
    2. 浏览器cookie长度有限制,一般为4k,不同浏览器限制不同,如果session数据过大,浏览器会保存不了

SpringSession原理:

     首先导入 RedisHttpSessionConfiguration 配置类,这个类在容器中添加了 RedisIndexedSessionRepository 组件,	这个组件就是用来存让装饰后的session的bean,相当于是redis操作session的dao[增删改查],同时它又继承了 SpringHttpSessionConfiguration 配置类, 这个类对包装后的Cookie进行了初始化.当服务启动的时候 这个类会自动注入	SessionRepository [我们自己写的配置文件就实现了这个接口]这个组件又在容器中注册了一个springSessionRepositoryFilter 过滤器	;这个过滤器将原生的request、response、session包装成 SessionRepositoryRequestWrapper,以后对session的操作都将在redis进行了

源码一步步分析:

  • @EnableRedi
  • @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)
    @Documented
    @Import(RedisHttpSessionConfiguration.class)
    @Configuration(proxyBeanMethods = false)
    public @interface EnableRedisHttpSession
RedisHttpSessionConfiguration extends SpringHttpSessionConfiguration

这个类是用来配置redis作为存储的分布式session配置类,类似的还有RedissonHttpSessionConfiguration用来做分布式锁

@Bean
	public RedisIndexedSessionRepository sessionRepository

这个配置类向容器中加入了一个RedisIndexedSessionRepository
,这个组件的作用是存储“装饰后的”RedisSessionRepository,相当于操作redis的session dao接口。

  • 同时还继承了SpringHttpSessionConfiguration
  • SpringHttpSessionConfiguration会初始化一个cookie序列化器,这为我们配置自定义cookie做了一个铺垫
@PostConstruct
	public void init() {
   
		CookieSerializer cookieSerializer = (this.cookieSerializer != null) ? this.cookieSerializer
				: createDefaultCookieSerializer();
		this.defaultHttpSessionIdResolver.setCookieSerializer(cookieSerializer);
	}
  • 还向容器中注入了一个SessionRepositoryFilter,相当于注入了一个filter
@Bean
	public <S extends Session> SessionRepositoryFilter<? extends Session> springSessionRepositoryFilter(
			SessionRepository<S> sessionRepository) {
   
		SessionRepositoryFilter<S> sessionRepositoryFilter = new SessionRepositoryFilter<>(sessionRepository);
		sessionRepositoryFilter.setHttpSessionIdResolver(this.httpSessionIdResolver);
		return sessionRepositoryFilter;
	}

	里面有个方法覆盖了父类filter的doFilterInternal
		@Override
	protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
			throws ServletException, IOException {
   
		request.setAttribute(SESSION_REPOSITORY_ATTR, this.sessionRepository);

		SessionRepositoryRequestWrapper wrappedRequest = new SessionRepositoryRequestWrapper(request, response
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值