Spring-data-redis 的实现原理
强烈建议阅读 Spring-session原理 的"2.spring-session重写servlet request 及 redis实现存储相关问题"
另外在写作中,适当参考了下面的文章。 它们的分析并不完全符合本文的场景,但都有值得参考之处 :
我们知道,引入spring-data-redis后,request.getSession()的行为将会从redis中寻找,为什么会这样呢?简单来说,这是因为SessionRepositoryFilter被添加到Servlet拦截链,将request和response替换了。
它是这样起作用的:
SessionRepositoryFilter是如何被生成、加入拦截链的呢?
参考 https://zhuanlan.zhihu.com/p/75776430 ,一切得从@EnableRedisHttpSession讲起:
@EnableRedisHttpSession直接引入了RedisHttpSessionConfiguration。
看下该类的定义:
上面两张图暴露两个信息:
跟着第一点的思路,我们看下父类SpringHttpSessionConfiguration。生成了SessionRepositoryFilter,我们看下父类:
可知,该方法会接受springboot自动注入的SessionRepository<S>为参数,并以此构建SessionRepositoryFilter。而回忆前面提到的,这个参数就是RedisHttpSessionConfiguration中提供的RedisOperationsSessionRepository。
这一章的总结了包含了RedisOperationsSessionRepository的SessionRepositoryFilter,是如何被生成为Bean的。我们之后会提到,这个Bean是如何加入拦截链的
首先,spring-boot-autoconfigure里的spring.factories里有提到SessionAutoConfiguration。springboot就会自动加载该类(不知道为什么会自动加载的话,建议先百度springboot自动加载原理)。
我们看下该类的定义:
其中的 @Import... 导入了SessionRepositoryFilterConfiguration。看下定义:
SessionRepositoryFilterConfiguration是一个 @Configuration ,我们分析下这个类:
在此处debug,会得到以下信息,供读者参考:
接下来我们要分析FilterRegistrationBean。
根据Servlet3.0规范 ,这种Bean会被自动调用onStartup方法。这个方法的行为是把内部的filter注册,而上文提到这里的filter就是SessionRepositoryFilter。
关于Servlet3.0,可参考 https://www.cnblogs.com/duanxz/archive/2012/10/25/2738173.html
之后,ServletRegistrationBean::onStartup到底是如何被调用的呢?它内部又是如何注册filter的呢?这就不是本文需要关注的了。 我们只需要知道,SessionRepositoryFilter在此会被加入拦截链,而它之后又会在拦截链中替换Request、Response,从而更改Session的行为是查看redis 。