千家信息网

springboot2.0.6中SpringApplication实例初始化

发表于:2026-11-03 作者:千家信息网编辑
千家信息网最后更新 2026年11月03日,这篇文章主要介绍"springboot2.0.6中SpringApplication实例初始化",在日常操作中,相信很多人在springboot2.0.6中SpringApplication实例初始化
千家信息网最后更新 2026年11月03日springboot2.0.6中SpringApplication实例初始化

这篇文章主要介绍"springboot2.0.6中SpringApplication实例初始化",在日常操作中,相信很多人在springboot2.0.6中SpringApplication实例初始化问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"springboot2.0.6中SpringApplication实例初始化"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

SpringApplication实例初始化

public SpringApplication(ResourceLoader resourceLoader, Class... primarySources) {        // 设置资源加载器属性        this.resourceLoader = resourceLoader;        // 校验主要加载资源不能为空,为空抛出异常        Assert.notNull(primarySources, "PrimarySources must not be null");        // 设置primarySources(主要来源)属性【后面会交给BeanDefinitionLoader,其分别load这些 primarySources 设置到scanner(扫描仪)中,避免重复扫描这些类进入容器】        this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));        // 获取ApplicationContext类型,并设置到webApplicationType属性中        this.webApplicationType = WebApplicationType.deduceFromClasspath();    // 获取应用上下文初始化器实例集合,并设置到initializers属性中        setInitializers((Collection) getSpringFactoriesInstances(                                ApplicationContextInitializer.class));    // 获取应用监听器实例集合,并设置到listeners属性中        setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));        // 找出main(主入口应用类)类,这里是CoreServerApplication类        this.mainApplicationClass = deduceMainApplicationClass();}

1. webApplicationType 是一个枚举类,用来判断当前的springboot项目是什么类型的。

  1. NONE:既不是运行在 web 容器下的应用并且也不应该启动一个内置的web服务。

  2. SERVLET:是需要运行在基于 servlet 的web应用且需要启动一个内置 servlet-web 服务。

  3. REACTIVE:还是运行在 reactive 的web应用中且需要启动一个 reactive-web 服务。

2. WebApplicationType.deduceFromClasspath() 获取获取ApplicationContext类型

private static final String[] SERVLET_INDICATOR_CLASSES = { "javax.servlet.Servlet",      "org.springframework.web.context.ConfigurableWebApplicationContext" };private static final String WEBMVC_INDICATOR_CLASS = "org.springframework."      + "web.servlet.DispatcherServlet";private static final String WEBFLUX_INDICATOR_CLASS = "org."      + "springframework.web.reactive.DispatcherHandler";private static final String JERSEY_INDICATOR_CLASS = "org.glassfish.jersey.servlet.ServletContainer";private static final String SERVLET_APPLICATION_CONTEXT_CLASS = "org.springframework.web.context.WebApplicationContext";private static final String REACTIVE_APPLICATION_CONTEXT_CLASS = "org.springframework.boot.web.reactive.context.ReactiveWebApplicationContext";static WebApplicationType deduceFromClasspath() {   if (ClassUtils.isPresent(WEBFLUX_INDICATOR_CLASS, null)         && !ClassUtils.isPresent(WEBMVC_INDICATOR_CLASS, null)         && !ClassUtils.isPresent(JERSEY_INDICATOR_CLASS, null)) {      return WebApplicationType.REACTIVE;   }   for (String className : SERVLET_INDICATOR_CLASSES) {      if (!ClassUtils.isPresent(className, null)) {         return WebApplicationType.NONE;      }   }   return WebApplicationType.SERVLET;}

根据org.springframework.util.ClassUtils的静态方法 isPresent 判断classpath里面是否有包含 WEBFLUX_INDICATOR_CLASS 并且没有包含 WEBMVC_INDICATOR_CLASS 和 JERSEY_INDICATOR_CLASSERVLET_INDICATOR_CLASSE ,满足条件则表示启动一个 REACTIVE 类型的WEB应用,不满足上述条件且有 SERVLET_INDICATOR_CLASSES 包含的类,则表示启动一个 SERVLET 类型的WEB应用,否则启动一个标准应用。

是否启动一个WEB应用就是取决于 classpath 下是否满足有 javax.servlet.Servlet 和 org.springframework.web.context.ConfigurableWebApplicationContext 或有 org. springframework.web.reactive.DispatcherHandler 并且没有org.springframework.web.servlet.DispatcherServlet 和 org.glassfish.jersey.servlet.ServletContainer。

3. setInitalizers()

初始化 classpath 下的所有的可用的 ApplicationContextInitializer

ApplicationContextInitializer 应用程序初始化器,做一些初始化的工作,是 springboot 准备调用 prepareContext 方法准备 spring 容器(此时spring容器已经创建需要refresh)之前调用的用来在这个时间点执行一些操作:比如设置 servletContext 等

默认情况下,getSpringFActoriesInstances 方法从 spring.factories 文件中找出key为 ApplicationContextInitializer 类型的权限定名称集合有:

  • org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer:

    • 向应用上下文中注册后置处理器(ConfigurationWarningsPostProcessor)

  • org.springframework.boot.context.ContextIdApplicationContextInitializer

    • 设置应用上下文ID,并将上面生成的ContextId(ContextIdApplicationContextInitializer)对象,作为一个单例bean注册到当前应用上下文。

  • org.springframework.boot.context.config.DelegatingApplicationContextInitializer

    • 执行环境属性"context.initializer.classes"指定的初始化器,然后执行这些初始化器。这里实现springboot应用程序自己实现的ApplicationContextInitializer对应用程序做一些初始化工作。

  • org.springframework.boot.context.web.ServerPortInfoApplicationContextInitializer

    • 把自己作为监听器注册到应用上下文中

  • org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer

    • 向应用上下文中注册后置处理器(CachingMetadataReaderFactoryPostProcessor)

  • org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener

    • 向应用上下文中注册监听器(ConditionEvaluationReportListener)当应用上下文实现GenercApplicationContext时,则设置"report"属性

( 图1-2 spring-boot.jar 中 spring.factories文件中applicationContextInitializer相关)

( 图1  执行getSpringFactoriesInstances(ApplicationContextInitializer.class)获取 spring.factories文件中applicationContextInitializer相关的工厂类,并进行初始化)

( 图2 springApplication对象中instances属性值)

4. setListeners()

初使化 classpath 下的所有的可用的 ApplicationListener

ApplicationListener 应用程序事件(ApplicationEvent)监听器

这里的应用程序事件(ApplicationEvent)有应用程序启动事件(ApplicationStartedEvent),失败事件(ApplicationFailedEvent),准备事件(ApplicationPreparedEvent)等

应用程序事件监听器跟监听事件是绑定的。比如 ConfigServerBootstrapApplicationListener 只跟 ApplicationEnvironmentPreparedEvent 事件绑定, LiquibaseServiceLocatorApplicationListener 只跟 ApplicationStartedEvent 事件绑定,LoggingApplicationListener 跟所有事件绑定等

默认情况下,getSpringFactoriesInstances 方法从 spring.factories 文件中找出key为 ApplicationListener 类型的,类全限定名称集合有:

  • org.springframework.boot.autoconfigure.BackgroundPreinitializer

  • org.springframework.boot.ClearCachesApplicationListener

  • org.springframework.boot.builder.ParentContextCloserApplicationListener

  • org.springframework.boot.context.FileEncodingApplicationListener

  • org.springframework.boot.context.config.AnsiOutputApplicationListener

  • org.springframework.boot.context.config.ConfigFileApplicationListener

  • org.springframework.boot.context.config.DelegatingApplicationListener

  • org.springframework.boot.context.logging.ClasspathLoggingApplicationListener

  • org.springframework.boot.context.logging.LoggingApplicationListener

  • org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener

( 图3-1 spring-boot.jar 中 spring.factories文件中applicationlistener相关)

( 图3-2 spring-boot.jar 中 spring.factories文件中applicationlistener相关)

( 图4  执行getSpringFactoriesInstances(Applicationlistener.class)获取 spring.factories文件中applicationContextInitializer相关的工厂类,并进行初始化)

  1. 由于spring 有一大堆事件比如 ContextRefreshedEvent,ContextStartedEvent 等等 我们有一个 ApplicationListener 就会监听到这些事件进而做相应的处理。

  2. 其实都是 applicationContext 调用其 publishEvent 发送一些 event,该方法会从很多 listener 中找到对该 event 感兴趣的 listener 调用其 onApplicationEvent,而实现这些的就是 SimpleApplicationEventMulticaster,如果有 Executor,其会优先使用Executor来执行这就可能导致我们的回调是异步的。

  3. applicationContext 还会把event传播到其父容器(我们知道我们常用到AnnotationConfigApplicationContext 已经其有很多父容器)

  4. 这边还有一个策略就是如果 earlyApplicationEvents 存在 则先把事件加入到 earlyApplicationEvents,稍后在发送,如果不存在则直接发送。

  5. applicationevent 中包含时间戳,springboot 启动类(source),还有我们的spring容器

5. 自定义ApplicationContextInitializer 和 ApplicationListener

如果我们想自己在代码中写 ApplicationContextInitializer 和 ApplicationListener 的实现类时候可以采用下列方式:

  • 在项目中建立一个 META-INF/spring.factories 文件,里面以 key=value 存放我们的实现类

  • 手动调用 SpringApplication 的对应添加方法也可以

  • 在我们的 application.properties 里面配置 context.initializer.classes = 实现类(通过 DelegatingApplicationContextInitializer 获取到我们配置的 initializer,进而可以保证在 prepareContext 时候调用),context.listener.classes = 实现类(无法监听到 springboot 启动时候的一些事件,因为那个时候该实现类还未加入容器)

  • 虽然我们使用 @Configuration 来讲我们 ApplicationListener 的实现类加入到spring容器,且也能监听到程序正常运行的一些事件(无法监听到 springboot 启动时候的一些事件,因为那个时候该实现类还未加入容器),但是 我们如果想监听全部的事件最好使用上述三种方式配置这样可以在 springboot 启动的时候就监听

6. getSpringFactoriesInstances()

通过系统加载类去指定目录下根据 propties 文件获取对应的 class 的全限定名称

总结

SpringApplication 的构造方法主要就是设置 Initializers 和 Listeners 同时设置 primaryClass 方便后面先去加载 primaryClass,而且也顺便确定了当前的 springboot 的运行环境

到此,关于"springboot2.0.6中SpringApplication实例初始化"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

应用 事件 容器 文件 上下 上下文 属性 方法 程序 监听 实例 应用程序 时候 类型 监听器 运行 就是 学习 名称 准备 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网科技工作委员会副主任毛军 互联网金融监管科技数据 科技互联网政务服务 与互联网科技公司 互联网科技视频素材 互联网科技公司做什么 互联网实体化科技化 广州优美互联网科技 深圳国际航运科技和互联网 福州新华互联网科技学校 知乎 健康食品互联网创新科技园项目 工业互联网等科技实现智能化赋能 中国互联网有什么科技 互联网领先科技宣传片 萌小萌互联网科技河南有限公司 国产互联网科技公司 互联网高科技行业有哪些企业 互联网界的黑科技 张家口科技产业互联网平台 互联网的黑科技实验室 江苏根荣互联网科技 互联网的科技 腾讯科技 互联网女皇 丰台科技园 互联网公司 茂名市互联网科技产业园 新兴科技互联网创新大赛颁奖典礼 互联网科技大奖都有哪些公司 徐州市互联网科技有限公司 兰石爱特工业互联网科技分公司 互联网高科技绘画
0