| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> Java知识库 -> 浅谈SpringMVC源码之SpringServletContainerInitializer的完整加载流程 -> 正文阅读 |
|
[Java知识库]浅谈SpringMVC源码之SpringServletContainerInitializer的完整加载流程 |
本文主要讲解的是SpringMVC不使用web.xml文件,而是使用JavaConfig的方式完成对SpringMVC配置的配置。即换一种方式完成DispatcherServlet等类的配置。 参考文章:SpringMVC 通过java类配置(不通过web.xml和xml 配置文件方式) 通过本文,你将了解到: 一、JDK的SPI机制
我看到网上有人写的挺详细的,如果你还不知道这个机制,可以参考参考这篇文章:深入理解SPI机制 总结下来就是一句话,JDK会自动加载META-INF/services目录下的类。
又如本篇文章的重点SpringMVC: 我们的故事就从这里说起 二、SpringServletContainerInitializer
1、@HandlesTypes(WebApplicationInitializer.class)在类上有一个@HandlesTypes注解,该注解的作用为,获取到所有的实现了WebApplicationInitializer接口的类,然后赋值给onStartup方法的webAppInitializerClasses参数。官方话术为,获取当前类(SpringServletContainerInitializer)感兴趣的类(WebApplicationInitializer)信息。 2、WebApplicationInitializer
前文介绍了@HandlesTypes注解的作用,最终的效果就是,在符合不是接口、不是抽象类等要求的基础上,执行实现了WebApplicationInitializer接口的类的onStartup方法。我们不难发现,系统默认的接口实现类都是不符合要求的,这就是我们通过JavaConfig方式配置的流程中有一步是继承抽象类AbstractAnnotationConfigDispatcherServletInitializer,然后重写对应的方法即可。 然后以我们自定义的类为起点,加载对应的onStartup方法,它会调用到它父类的父类中的onStartup方法(父类的父类中有实现) 该层级的设计是基于模板方法的设计模式进行设计的。为了方便查看,我根据类的关系和类中方法的作用整理成了下面的结构图: 由图我们可以得出:
只要你明白了这个层级关系,剩下的代码就很简单了。一定要多理几遍这个关系,这对于后面的整体理解都起着至关重要的作用 3、AbstractDispatcherServletInitializer
1)父类初始化步骤 初始化ContextLoaderListener的时候传入的参数为父容器。这在第三节的赋值阶段会再次使用到 代码片段在AbstractContextLoaderInitializer 2)当前类初始化步骤 创建DispatcherServlet方法的时候,传入的是子容器。 代码片段在AbstractDispatcherServletInitializer类中 3)创建子容器
代码片段在AbstractAnnotationConfigDispatcherServletInitializer类中 以上的过程,我们就可以等价于使用xml形式的配置Spring 这个过程中还有两个重点,分别是ContextLoaderListener和DispatcherServlet,我在后面单独讲解 三、ServletContextListener初始化
前面只是完成对该类的实例化,即已经完成相关参数的赋值。在启动Tomcat的时候,根据Listener的生命周期,容器我们会调用ContextLoaderListener类中的contextInitialized方法,执行相关的逻辑。 1、contextInitialized
代码片段在ContextLoader类中 2、configureAndRefreshWebApplicationContext
代码片段在ContextLoader类中 至此,父容器相关的准备工作已经处理完成 四、HttpServlet初始化
我们都知道SpringMVC的底层就是封装了Servlet。以至于我们在编写Controller层接口的时候,不再是去继承HttpServlet 类,重写对应的doGet、doPost方法… 现在我们只需要添加一个@Controller注解,添加对应的@RequestMapping映射即可完成一个接口的编写。这一切的一切都要从Spring为我们编写的一个Servlet说起,他就是DispatcherServlet。而这个类就是我们前面在创建子容器的时候初始化出来的 查看该类的继承关系,我们可以得到如下的关系图谱。而对应的调用关系也从这里开始。 这里需要补充Servlet的生命周期说明 Servlet 生命周期可被定义为从创建直到毁灭的整个过程。以下是 Servlet 遵循的过程:
1、init即我们Servlet方法的调用位置为init方法,此时跳转到HttpServletBean类的init方法 该代码片段在HttpServletBean类中 接下来的几步调用都比较常规 init() --> initServletBean() --> initWebApplicationContext() 2、initWebApplicationContext
该代码片段在FrameworkServlet类中 3、configureAndRefreshWebApplicationContext
该代码片段在FrameworkServlet类中 4、ContextRefreshListener监听器是一个十分重要的点,因为后面DispatcherServlet在处理器映射器、处理器适配器、视图解析器的数据转发的时候会用到这些初始化map中的数据 对应的方法跳转逻辑:onApplicationEvent --> onRefresh --> onRefresh --> initStrategies 该代码片段在FrameworkServlet类中 选择其中一个map数据进行讲解,下图是初始化HandlerMapping的数据:
该代码片段在FrameworkServlet类中 我们可以看到HandlerMapping接口的实现中,就有我们熟悉的BeanNameUrlHandlerMapping和RequestMappingHandlerMapping 至此,SpringMVC所需要的前期准备工作大致已经完成。 |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/23 21:04:54- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |