spring-session源码解读-2
该注解有两个元注解,一个是Configuration, 一个是Import, 上一篇提过Configuration,它就相当于是beans配置,而Import则相当于是beans里嵌套了另一个beans配置项。另外再介绍一下Bean这个注解,这个注解相当于是beans配置里的bean标签,它是注解在方法上的,被注解方法的返回值就是一个spring bean,而相应的方法名就是作为bean name,如果显示的设置了name属性,那就以name属性值作为bean name。
所以可以理解为EnableRedisHttpSession就是一个编程式的配置定义,而RedisHttpSessionConfiguration显然也应该是一个编程式配置定义。
容器对springSessionRepositoryFilter的依赖管理在RedisHttpSessionConfiguration里很惊喜的发现了第一篇里被注入的“springSessionRepositoryFilter”。
@Bean public S extends ExpiringSession SessionRepositoryFilter ? extends ExpiringSession springSessionRepositoryFilter(SessionRepository S sessionRepository, ServletContext servletContext) { SessionRepositoryFilter S sessionRepositoryFilter = new SessionRepositoryFilter S (sessionRepository); sessionRepositoryFilter.setServletContext(servletContext); if(httpSessionStrategy != null) { sessionRepositoryFilter.setHttpSessionStrategy(httpSessionStrategy); return sessionRepositoryFilter; }
这里相当于是定义了一个bean-name=”springSessionRepositoryFilter” >
两个参数SessionRepository和ServletContext都是由Spring容器管理的依赖,SessionRepository和SpringSessionRepositoryFilter定义在同一个Configuration里。ServletContext的注入可能会比较令人疑惑,在这个Configuration没有定义它无法定义它,因为它是由Servlet容器生成的。
ContextLoaderListener在介绍ServletContext的依赖之前,再聊下前文提过的ContextLoaderListener。它由initializer动态注册,其构造函数参数为一个WebApplicationContext,继承于ContextLoader(实际启动WebApplicationContext初始化工作的对象),构造函数参数是一个WebApplicationContext。
Servlet容器启动时会通知ContextLoaderListener,
@Override public void contextInitialized(ServletContextEvent event) { initWebApplicationContext(event.getServletContext()); }
ContextLoaderListener会调用父类ContextLoader的initWebApplicationContext方法来启动ApplicationContext的初始化,
public WebApplicationContext initWebApplicationContext(ServletContext servletContext) { configureAndRefreshWebApplicationContext(cwac, servletContext); servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context); return this.context; }
上面只抽取了ContextLoader的关键逻辑
1. ApplicationContext被默认放入了ServletContext中,key是个默认值。上一篇提过在获取对应name的filter时会从ServletContext里先得ApplicationContext,再获取对应依赖。
2. configureAndRefreshWebApplicationContext这个方法最终启动了ApplictionContext的最核心refresh,这个方法被放在公共抽象类AbstractApplicationContext里,几乎所有的ApplicationContext都会执行。这个阶段结束后,ApplicationContext也就启动完毕,整个容器的依赖也就完成。因为篇幅太长ApplicationContext启动的细节就不再展开。
在容器refresh阶段会通过postProcessBeanFactory这个策略方法对容器对应的BeanFactory做后处理,一般是设置一些beanPostProcessor之类,对于WebApplicationContext则会处理ServletContext的依赖。
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext, this.servletConfig)); beanFactory.ignoreDependencyInterface(ServletContextAware.class); beanFactory.ignoreDependencyInterface(ServletConfigAware.class); //在这里将ServletContext 作为一个bean管理起来WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext); WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext, this.servletConfig); }
至此,springSessionRepositoryFilter的依赖也注入完毕。综合1,2两篇基本上就了解了filter是如何被spring容器管理并如何通过代理动态注册给容器的。那么这个拦截器究竟能做什么?这就留到后面专门通过一篇文章来展开
Spring Session 的原理 今天在写一个对外接口, 这个接口大致原理是在过滤器中通过 token 获取用户信息然后创建 session, 后续的流程就是 `Controller - Service - Dao` 了. 这次开发没有像之前那样愣头愣脑的, 我想了一下, 对方调用的时候是没有 session id 的, 也就是每次认证之后都会创建一个 session. 那这就可能存在一个大问题了, 假设调用次数非常多的话, 会创建茫茫多的 session, 可能会击垮系统.
19、springcloud分布式Session之Spring Session HttpSession是通过Servlet容器创建和管理的,像Tomcat/Jetty都是保存在内存中的。但是把应用搭建成分布式的集群,然后利用F5、LVS或Nginx做负载均衡,那么来自同一用户的Http请求将有可能被分发到多个不同的服务器中。
阿里特邀专家徐雷Java Spring Boot开发实战系列课程(第18讲):制作Java Docker镜像与推送到DockerHub和阿里云Docker仓库 立即下载
相关文章
- Spring MVC框架:第十二章:运行原理
- Spring学习笔记(三)——Spring注解开发&spring与Junit整合测试
- Spring Framework 源码学习笔记(六)
- 通过@MapperScan源码了解Spring自定义注解扫描器[通俗易懂]
- Spring MVC注解Controller源码流程解析--定位HandlerMethod
- 【03】Spring源码-手写篇-手写AOP实现(上)
- 【05】Spring源码-手写篇-手写Bean配置
- 【06】Spring源码-分析篇-ApplicationContext
- 【09】Spring源码-分析篇-DI源码分析
- 【10】Spring源码-分析篇-AOP源码分析
- Spring Security 4入门
- Spring - FactoryBean扩展实战_MyBatis-Spring 启动过程源码解读
- Spring Boot整合分布式搜索引擎ElasticSearch 实现相关基本操作
- 【Spring源码】- 05 扩展点之BeanPostProcessor
- 第一个Spring程序
- spring的AOP(五)—-Spring AOP 编程(AspectJ )详解编程语言
- Spring isTypeMatch方法:判断JavaBean是否匹配指定的类型
- Spring框架下整合Redis的实现(spring整合redis)