Google 微软 Apple Java 无人驾驶 人工智能 大数据 阿里巴巴 特斯拉 Facebook VR/AR 安全 手机 亚马逊 机器人 云计算
DispatcherServlet 和 ContextLoaderListener 的关系,到底用哪个?

DispatcherServlet 和 ContextLoaderListener 的关系,到底用哪个?

我们先看下这两个东东的配置方法:

DispatcherServlet 和 ContextLoaderListener 的关系,到底用哪个?

对于contextConfigLocation参数,有2个地方可以配置:
1)context-param 是全局性配置
2)servlet下的init-param 是局部性配置
若以上两处都设置了一个相同的bean配置文件路径,那么该文件内配置的bean会被初始化2次,所以一个配置文件只能选择一种配置位置
项目中使用spring框架有2种方式:
1)listener下的ContextLoaderListener 是一种引入方式,默认读取/WEB-INF/applicationContext.xml
2)若是spring-web项目,DispatcherServlet 也是一种引入方式,默认读取/WEB-INF/${servlet-name}-servlet.xml
倘若以上2种配置都引入了,那么全局性的bean配置文件会被加载2次;而且2种方式的各自配置文件里的配置项在某种意义上并不是合并互补,而是各成一个体系(虽然普通的bean看似是都加载到全局上下文来了,但还是有一些特殊bean和配置项没有按预期的那样工作);
比如/WEB-INF/applicationContext.xml文件下里的AOP声明式配置:
<!--aop 行为-->
<bean id="himvn" class="com.tangbao.hellomvn.Himvn" />
<!--aop 注释方式-->
<bean id="hiaspect" class="com.tangbao.hellomvn.Hiaspect" />
<!--aop config-->
<aop:aspectj-autoproxy />
<aop:config>
    <aop:aspect id="aoplianxi" ref="himvn">
        <aop:pointcut id="test1" expression="execution(* com.tangbao.controller.RestlessController.RestlessController(..))"></aop:pointcut>
        <aop:before method="sayHi" pointcut-ref="test1"></aop:before>
        <aop:after method="sayHi" pointcut-ref="test1"></aop:after>
    </aop:aspect>
</aop:config>
若只是在全局配置项中,而没有在DispatcherServlet 中加载,那么此aop会无效。
DispatcherServlet 和 ContextLoaderListener 的关系,到底用哪个?
所以,在web项目中,就不要使用ContextLoaderListener 和全局配置contextConfigLocation参数了,统一在DispatcherServlet 下配置,应该就不那么混乱了。如下:
DispatcherServlet 和 ContextLoaderListener 的关系,到底用哪个?
这样结果就如我们的预期:多bean配置文件不会出现重复加载,所有aop配置也都生效。
以上论点是在spring4.3.1下测试所得,从表现猜测本质。
点赞 0 打赏

我要评论