SpringBoot构造流程源码分析:Web应用类型推断
Web应用类型推断完成变量赋值之后 , 在 SpringApplication 的构造方法中便调用了 WebApplication Type 的deduceFromClasspath 方法来进行 Web 应用类型的推断 。 SpringApplication 构造方法中的相关代码如下 。
public SpringApplication(ResourceLoader resourceLoader, Class>... primarySources) {this . webApplicationType = WebApplicat ionType . deduceFromClasspath();}
该行代码调用了 WebApplicationType 的 deduceFromClasspath 方法 , 并将获得的 Web 应用类型赋值给私有成员变量 webApplicationType.
WebApplicationType 为枚举类 ,它定义了可能的 Web 应用类型 , 该枚举类提供了三类定义:枚举类型、推断类型的方法和用于推断的常量 。 枚举类型包括非 Web 应用、基于 SERVLET 的 Web 应用和基于 REACTIVE 的 Web 应用 , 代码如下 。
public enum WebApplicationType {//非 web 应用类型NONE,//基于 SERVLET 的 Web 应用类 型SERVLET ,//基 FREACTIVE 的 eb 应用类型REACTIVE;}
WebApplicationType 内针对 Web 应用类型提供了两个推断方法:
deduceFromClasspath 方法和 deduceFromApplicationContext 方法 。 在此我们使用了deduceFromClasspath 方法 , 下面重 点分析该方法的实现 。
public enum WebApplicationType {..private static final String[] SERVLET_ INDICATOR_ CLASSES = { "javax. servlet . Servlet","org. springframework . web . context . ConfigurableWebApplicationContext" }private static final String WEBMVC_ INDICATOR_ CLASS = "org. springframewor+ "web. servlet . DispatcherServlet";private static final String WEBFLUX_ INDICATOR_ _CLASS = "org.'+ "springframework. web. reactive . DispatcherHandler";private static final String JERSEY INDICATOR_ CLASS = "org. glassfish.jerseyservlet. ServletContainer";//基于 classpath 的 web 应用类型推断 , 核心实现方法为 ClassUtils. isPresentstatic WebApplicationType deduceF romClasspath() {if (ClassUtils. isPresent (WEBFLUX_ INDICATOR_ CLASS, null)for (String className : SERVLET_ INDICATOR_ CLASSES) {if (!ClassUtils. isPresent(className, nul1)) {return WebApplicationType . NONE;return WebApplicationType . SERVLET;}
方法 deduceFromClasspath 是基于 classpath 中类是否存在来进行类型推断的 , 就是判断指定的类是否存在于 classpath 下 ,并根据判断的结果来进行组合推断该应用属于什么类型 。 deduceFromClasspath 在判断的过程中用到了 ClassUtils 的 isPresent 方法 。 isPresent方法的核心机制就是通过反射创建指定的类 , 根据在创建过程中是否抛出异常来判断该类是通过上面的源代码 , 我们可以看到 deduceFromClasspath 的推断逻辑如下 。
.当 DispatcherHandler 存在 , 并且 DispatcherServlet 和 ServletContainer 都不存在 , 则返回类型为 WebApplicationType.REACTIVE.
.当 SERVLET 或 ConfigurableWebApplicationContext 任何一个不存在时 , 说明当前应用为非 Web 应用 , 返回 WebApplicationType NONE 。
当应用不为 REACTIVE Web 应用 , 并且 SERVLET 和 ConfigurableWebApplicationContext都存在的情况下 , 则为 SERVLET 的 Web 应用 , 返回 WebApplicationType .SERVLET.
文章插图
ApplicationContextlnitializer加载源码解析
ApplicationContextlnitializer是SpringIOC 容器提供的一个接口 , 它是一个回调接口 , 主要目的是允许用户在 ConfigurableApplicationContext 类型(或其子类型)的 ApplicationContext做 refresh 方法调用刷新之前 , 对 ConfigurableApplicationContext 实例做进一步的设 置或处理 。 通常用于应用程序上下文进行编程初始化的 Web 应用程序中 。
- 文件系统(02):基于SpringBoot管理Xml和CSV
- SpringBoot2.x入门到项目实战课程系列(第二章)
- SpringBoot集成Mybatis
- 大牛深入解析SpringBoot核心运行原理和运作原理源码
- SpringBoot写后端接口,看这一篇就够了
- 美国跨境物流空运FBA双清到门是什么操作流程呢?
- SpringBoot2.x入门到项目实战课程系列(第五章)
- SpringBoot整合JWT+Shiro
- 不做CRUD的我开源了Springboot API一键生成器
- DispatcherServlet执行流程