Spring Boot源码(二):SPI去除web.xml
SPI广泛用于dubbo,spring boot,spring cloud alibaba等
关于SPI,可见SPI-Service Provider Interface
继续上篇文章
上面三句代码的意思是创建IOC容器,下面是向容器中注入DispatcherServlet。
而ContextLoaderListener这个类的作用就是启动IOC容器,所以它们作用一致。
现在来看spring web怎么写的。
官方项目就是用的SPI来创建实例,我们聚焦于SpringServletContainerInitializer
- /**
*类的描述:spring应用一启动(tomcat启动的时候)就会去扫描当前应用下导入jar包的META-INF/services的javax.servlet.ServletContainerInitializer的内容,
*就是SpringServletContainerInitializer,此类中通过@HandlesTypes把WebApplicationInitializer的所有实现类作为onStartup方法的入参,
*该方法对其中不是抽象类或接口的进行实例化
*/
@HandlesTypes(WebApplicationInitializer.class)- public class SpringServletContainerInitializer implements ServletContainerInitializer {
- /**
- * Delegate the {@code ServletContext} to any {@link WebApplicationInitializer}
- * implementations present on the application classpath.
- * <p>Because this class declares @{@code HandlesTypes(WebApplicationInitializer.class)},
- * Servlet 3.0+ containers will automatically scan the classpath for implementations
- * of Spring's {@code WebApplicationInitializer} interface and provide the set of all
- * such types to the {@code webAppInitializerClasses} parameter of this method.
- * <p>If no {@code WebApplicationInitializer} implementations are found on the classpath,
- * this method is effectively a no-op. An INFO-level log message will be issued notifying
- * the user that the {@code ServletContainerInitializer} has indeed been invoked but that
- * no {@code WebApplicationInitializer} implementations were found.
- * <p>Assuming that one or more {@code WebApplicationInitializer} types are detected,
- * they will be instantiated (and <em>sorted</em> if the @{@link
- * org.springframework.core.annotation.Order @Order} annotation is present or
- * the {@link org.springframework.core.Ordered Ordered} interface has been
- * implemented). Then the {@link WebApplicationInitializer#onStartup(ServletContext)}
- * method will be invoked on each instance, delegating the {@code ServletContext} such
- * that each instance may register and configure servlets such as Spring's
- * {@code DispatcherServlet}, listeners such as Spring's {@code ContextLoaderListener},
- * or any other Servlet API componentry such as filters.
- * @param webAppInitializerClasses all implementations of
- * {@link WebApplicationInitializer} found on the application classpath
- * @param servletContext the servlet context to be initialized
- * @see WebApplicationInitializer#onStartup(ServletContext)
- * @see AnnotationAwareOrderComparator
- */
- @Override
- public void onStartup(@Nullable Set<Class<?>> webAppInitializerClasses, ServletContext servletContext)
- throws ServletException {
- List<WebApplicationInitializer> initializers = new LinkedList<>();
- if (webAppInitializerClasses != null) {
- for (Class<?> waiClass : webAppInitializerClasses) {
- // Be defensive: Some servlet containers provide us with invalid classes,
- // no matter what @HandlesTypes says...
- if (!waiClass.isInterface() && !Modifier.isAbstract(waiClass.getModifiers()) &&
- WebApplicationInitializer.class.isAssignableFrom(waiClass)) {
- try {
- initializers.add((WebApplicationInitializer)
- ReflectionUtils.accessibleConstructor(waiClass).newInstance());
- }
- catch (Throwable ex) {
- throw new ServletException("Failed to instantiate WebApplicationInitializer class", ex);
- }
- }
- }
- }
- if (initializers.isEmpty()) {
- servletContext.log("No Spring WebApplicationInitializer types detected on classpath");
- return;
- }
- servletContext.log(initializers.size() + " Spring WebApplicationInitializers detected on classpath");
- AnnotationAwareOrderComparator.sort(initializers);
- for (WebApplicationInitializer initializer : initializers) {
- initializer.onStartup(servletContext);
- }
- }
- }
里面只有一个onStartup方法,而容器启动时会调用此方法。
我们着重看下@HandlesTypes 注解,官方解释:
- /**
- <p>Because this class declares @{@code HandlesTypes(WebApplicationInitializer.class)},
- * Servlet 3.0+ containers will automatically scan the classpath for implementations
- * of Spring's {@code WebApplicationInitializer} interface and provide the set of all
- * such types to the {@code webAppInitializerClasses} parameter of this method.
- */
@HandlesTypes 注解会把WebApplicationInitializer的所有子类(可用快捷键Ctrl+Alt+B)放到Set集合中:
然后循环判断此类不为抽象类,不为接口,并且是实现了WebApplicationInitializer接口的,然后实例化对象添加到initializers中:
然后对其进行排序:
这个排序就是通过@Order来判断先后顺序的(或者实现Order接口)。
然后分别循环子类的OnStartup方法。
Spring Boot源码(二):SPI去除web.xml的更多相关文章
- Spring Boot源码(一):去除web.xml
访问https://spring.io/ spring boot中: public class MyWebApplicationInitializer implements WebApplicatio ...
- Spring Boot源码中模块详解
Spring Boot源码中模块详解 一.源码 spring boot2.1版本源码地址:https://github.com/spring-projects/spring-boot/tree/2.1 ...
- 精尽Spring Boot源码分析 - SpringApplication 启动类的启动过程
该系列文章是笔者在学习 Spring Boot 过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring Boot 源码分析 GitHub 地址 进行阅读 Sprin ...
- 精尽Spring Boot源码分析 - 支持外部 Tomcat 容器的实现
该系列文章是笔者在学习 Spring Boot 过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring Boot 源码分析 GitHub 地址 进行阅读 Sprin ...
- 走进Spring Boot源码学习之路和浅谈入门
Spring Boot浅聊入门 **本人博客网站 **IT小神 www.itxiaoshen.com Spring Boot官网地址:https://spring.io/projects/spring ...
- 曹工说Spring Boot源码(2)-- Bean Definition到底是什么,咱们对着接口,逐个方法讲解
写在前面的话 相关背景及资源: 曹工说Spring Boot源码系列开讲了(1)-- Bean Definition到底是什么,附spring思维导图分享 工程代码地址 思维导图地址 工程结构图: 正 ...
- Spring Boot源码分析-配置文件加载原理
在Spring Boot源码分析-启动过程中我们进行了启动源码的分析,大致了解了整个Spring Boot的启动过程,具体细节这里不再赘述,感兴趣的同学可以自行阅读.今天让我们继续阅读源码,了解配置文 ...
- Spring Boot源码分析-启动过程
Spring Boot作为目前最流行的Java开发框架,秉承"约定优于配置"原则,大大简化了Spring MVC繁琐的XML文件配置,基本实现零配置启动项目. 本文基于Spring ...
- 曹工说Spring Boot源码(14)-- AspectJ的Load-Time-Weaving的两种实现方式细细讲解,以及怎么和Spring Instrumentation集成
写在前面的话 相关背景及资源: 曹工说Spring Boot源码(1)-- Bean Definition到底是什么,附spring思维导图分享 曹工说Spring Boot源码(2)-- Bean ...
- 曹工说Spring Boot源码(30)-- ConfigurationClassPostProcessor 实在太硬核了,为了了解它,我可能debug了快一天
写在前面的话 相关背景及资源: 曹工说Spring Boot源码(1)-- Bean Definition到底是什么,附spring思维导图分享 曹工说Spring Boot源码(2)-- Bean ...
随机推荐
- 2019icpc南京网络赛 A The beautiful values of the palace(离线+树状数组)
题意: (假设所有的点对应的值已经求出)给你一个1e6*1e6的矩阵,有m<=1e5个点有值,其余都为0 q<=1e5个询问,求子矩阵的权值和 思路: 根据二维差分,对于询问左下角(x1, ...
- BZOJ 1009 [HNOI2008]GT考试(矩阵快速幂优化DP+KMP)
题意: 求长度为n的不含长为m的指定子串的字符串的个数 1s, n<=1e9, m<=50 思路: 长见识了.. 设那个指定子串为s f[i][j]表示长度为i的字符串(其中后j个字符与s ...
- Github搜索技巧-如何使用github找到自己感兴趣的项目(转载)
Github现在不仅仅作为一个版本控制工具,更是一个开源的仓库,里面不但有优秀的开源代码,电子书,还有一些五花八门的项目,有些国家的法律也放在上面,作为程序员如何找到自己感兴趣的项目就非常重要了! 欢 ...
- NR / 5G - Uplink Carrier Waveform Generation
- pytorch -- CNN 文本分类 -- 《 Convolutional Neural Networks for Sentence Classification》
论文 < Convolutional Neural Networks for Sentence Classification>通过CNN实现了文本分类. 论文地址: 666666 模型图 ...
- logstash 配置文件语法
需要一个配置文件 管理输入.过滤器和输出相关的配置.配置文件内容格式如下: # 输入 input { ... } # 过滤器 filter { ... } # 输出 output { ... } 先来 ...
- php页面传递参数值几种方法总结
2013-06-06 18:02 (分类:) 又搞了一个学期的php,就这样吧. php是一种服务器的脚本语言,他也是现在最为流行的WEB开发语言,下面我们来讲述一下几种上在php开发应用中常用的四种 ...
- CCS过渡和动画
过渡 过渡能让使用过渡的元素在样式发生变化时(例如鼠标划过,单击按钮,点击图片时,颜色,尺寸,位置等样式发生变化),定义变化过程中的动画,让变化不再是瞬间产生. 过渡样式使用transition定义, ...
- 聊聊GIS数据的四个分层与GIS服务
本篇不讨论矢量栅格数据的结构,也不讨论矢量与栅格的区别(即设定读者有这方面的基础). 版权声明:原创.博客园/B站/小专栏/知乎/CSDN @秋意正寒 转载请标注原地址并声明转载: https://w ...
- Java工作流系统jflow从表功能介绍一
关键词:工作流快速开发平台 工作流流设计 业务流程管理 asp.net 开源工作流 bpm工作流系统 java工作流主流框架 自定义工作流引擎 表单设计器 流程设计器 从表也叫明细表, ...