关于Spring中的DispatcherServlet和ContextLoaderListener的配置源码解读

 在我们的spring项目搭建的过程中通常会使用web.xml会经常看到如下的配置:
在这里插入图片描述
 在web.xml中我们配置了一个ContextLoaderListener和一个DispatcherServlet,但是我们从来没有关心过为什么要在这里配置一个监听器和一个servlet,并且也没有考虑过如果不使用web.xml能不能实现这个功能。今天我们就来讲解一下这两个东西到底做了什么,再就是有没有其他的方案实现同样的效果。
 首先来说,web.xml中的配置能不能省去这两个配置改用其他方式呢答案是肯定的。在servlet 3.0以后提供了注解的方式来实现listener和servlet的注入,也就是说不止这两个东西可以省去整个web.xml都可以使用注解的方式去注入。但是呢这种注解的方式需要tomcat8的支持,所支持的注解主要有@WebServlet、@WebFilter、@WebListener等所以可以直接在程序中注入这个监听器和servlet,另外还可以通过另外的一种方式进行注入,那就是SPI(Service Provider In)技术,这种技术是一种服务发现机制,广泛引用与第三方服务的整合,比如jdbc就是采用了这种技术来实现的和项目的整合。这种方式的思路就是在项目中创建META-INF/services/文件夹然后在文件夹下创建一个文件名字叫做javax.servlet.ServletContainerInitializer然后在文件里边写上ServletContainerInitializer这个类的实现类。我们翻看spring的源代码可以发现在spring-web模块中有一个文件如图:
在这里插入图片描述
 其中SpringServletContainerInitializer就是ServletContainerInitializer的具体实现,这样就通过spi技术找到了对应的初始化类,到这里另外一个重点就来了,首先是SpringServletContainerInitialize
这个类继承了ServletContainerInitializer覆写了onStart方法,这个onstart方法会在web容器启动的时候被调用,同时在SpringServletContainerInitialize中使用了一个注解@HandlesTypes(
{WebApplicationInitializer.class})这个注解是在setrvlet中定义的使用了这个注解以后会将所有的WebApplicationInitializer的实现类通过一个set集合传入到onstart方法的形参上如图:
在这里插入图片描述
 在onstart方法中遍历了WebApplicationInitializer的实现类的class并且 对其实例化然后调用其onStart方法如图:
在这里插入图片描述
 到这里对于SPI的实现我们就讲完了,但是回到之前的问题这里和我们的web.xml中的监听器和servlet有什么关系呢?我们想下既然最中调用了WebApplicationInitializer实现类的onStart方法,那么我们去写一个类去实现WebApplicationInitializer并且在其onStart方法中去做我们需要做的事情不就可以了吗,所以说我们可以通过实现WebApplicationInitializer并在其onStart方法中去添加我们的监听器和servlet不就好了吗。但是贴心的spring早已为我们准备好了一个抽象类来供我 们实现他是AbstractAnnotationConfigDispatcherServletInitializer
在这里插入图片描述
 我们只需要继承他空实现其抽象方法就可以了,该类的继承关系如图:
在这里插入图片描述
在这里插入图片描述

从中可以看到在AbstractDispatcherServletInitializer中实现了onStart方法,所以就会调用其onStart方法,其方法如图:
在这里插入图片描述
其中调用了父类的onStart方法,并且注册了DispatcherServlet,在父类中的onStart方法中会发现我们的监听器被注册了:
在这里插入图片描述
 至此为止我们一开始讨论的问题如何不通过web.xml的方式加载DispatcherServlet和ContextLoaderListener就解决了。其实其中还省略了很多的细节,比如此时我们的spring的配置文件如何加载进去,其实在createRootApplicationContext方法中调用了getRootConfigClasses这个方法,这个方法是由我们的类自己去实现的也就是下图中的三个方法:
在这里插入图片描述
 这三个方法分别是获取spring的配置,获取springmvc的配置,配置DispatcherServlet的拦截路径分别代表了传统配置中的application.xml、springmvc.xml、springmvc配置中的下图红框部分
在这里插入图片描述
总结:
 在项目整合spring和springmvc的时候有三种方式来注册DispatcherServlet和ContextLoaderListener他们分别是:
 1.通过web.xml中的标签来指定
 2.通过注解@WebServlet @WebFilter @WebListener三种来将监听器和servlet注册,但是需要servlet 3.0和web容器的支持,其实这个方式只是web.xml的变形,就是使用代码替代了xml配置。
 3.通过SPI技术来实现

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值