spring的一些理解(2021年12月)

        最近的工作需要处理老项目的一些session共享的问题。老项目原本没有做session共享,负载均衡的策略是hash。因为后续需要做滚动升级,老项目注册进nacos后负载均衡的策略不能再沿用hash(滚动升级的原因)。考虑整合spring-session框架。

出现的问题

问题1

        老框架的spring版本为3.2.18,spring-session的版本只有1.0.0的版本应用的spring版本能匹配。就顺理成章准备引入1.0.0的版本。

问题2

        成功配置spring-session后项目报错,提示没有ContextLoaderListener。

查阅资料后发现,老项目的web.xml配置中没有配置ContextLoaderListener,注册的目的是为了初始化spring容器。没有spring容器项目是如何运行的呢?原来是把所有的原本需要spring容器去管理的bean信息等全部放到了mvc容器中去管理,mvc容器扫描了所有的bean。

        正常情况是spring配置文件扫描非controller层的包,controller层由mvc去扫描,controller层的mvc相关的注解需要由mvc容器初始化的时候去解析。且mvc容器可以访问自己的父容器spring容器(mvc容器初始化时把spring容器设置为parent)。

        为何整合了spring-session后报错了呢?

        spring-session做的事是注册了一个filter(springSessionRepositoryFilter),此filter被扫描后是一个spring bean。servlet容器是无法直接去访问spring的信息的,提供了注册filter的接口,spring通过实现ServletContainerInitializer接口,关注WebApplicationInitializer接口,通过ServletContext类中的方法注册filter,servlet,listener(servlet-api3.0后才有的方法)。注册springSessionRepositoryFilter时此filter还未实例化,通过bean名称注册一个DelegatingFilterProxy的filter代理。实际接受到请求后,此代理filter会根据bean名称找到已经实例化好的bean进行dofilter操作。但是DelegatingFilterProxy是spring-web包提供的,他不会去spring-mvc包才会注册的mvc容器中去寻找此bean(除非指定了想要寻找的容器setContextAttribute()方法,但是spring-session未设置),在spring容器中未找到springSessionRepositoryFilter(bean)则会抛出异常。

        但是老项目很多,不能一个个去改他们的配置,把bean分开至spring,springmvc两个容器中,所以只能考虑其他方式去实现。

感悟

        spring框架提供的控制反转(IOC)功能,可以很好的帮助我们管理项目中各个类的依赖关系进行解耦,核心是通过容器帮我们管理bean,再调节bean之间的依赖关系。原本的servlet容器管理filter,servlet,listener是必须的,这是servlet规范,tomcat等web服务器去实现。spring-web包提供了web开发的一些基本的框架,帮我们去更好的连接bean和filter,servlet,listener的关系。除了web包其他的核心组件和web开发本身没有特别大的联系,spring框架可以使用在非web项目中,但是现在生活中无法脱离网络,网络传输大多使用应用层的http协议,导致web包,mvc包等的使用更加多,在web包提供的基础上进行spring和servlet容器的交互。例如,spring-security,spring-cloud-gateway都是需要注册自己的filter,或是修改filter的路径实现的。

本人理解,如有错误,欢迎交流。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值