1   springboot启动时,只需要调用一个类前面加了@SpringBootApplication的main函数,执行SpringApplication.run(DemoApplication.class, args)即可,这里初始化了一个SpringApplication实例,然后调用run启动springboot。run方法中,调用了initialize,如下

@SuppressWarnings({ "unchecked", "rawtypes" })
private void initialize(Object[] sources) {

//把传入的source设置到SpringApplication的变量中 
  if (sources != null && sources.length > 0) {
    this.sources.addAll(Arrays.asList(sources));
  }

// 如果是web程序,设置web环境。web程序必须让类加载器存在servlet 和 ConfigurableWebApplicationContext
  this.webEnvironment = deduceWebEnvironment();

//找到ApplicationContextInitializer类实例化为成员变量,这个过程是找到所有的初始化器。
  setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
  //把ApplicationListener实例化为变量,就是找到所有的事件监听器。

setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));

//找到入口类,即放置main函数的类。

  this.mainApplicationClass = deduceMainApplicationClass();
}

(1)初始化context。 上面setInitializers 得到了ApplicationContextInitializer类型对象的集合,ApplicationContextInitializer是一个可以用来初始化各种ApplicationContex的接口,就一个initialize方法,上面初始化的时候用到了getSpringFactoriesInstances方法如下,

private <T> Collection<? extends T> getSpringFactoriesInstances(Class<T> type,Class<?>[] parameterTypes, Object... args) {
  ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
  // Use names and ensure unique to protect against duplicates
  Set<String> names = new LinkedHashSet<String>(SpringFactoriesLoader.loadFactoryNames(type, classLoader));
  List<T> instances = createSpringFactoriesInstances(type, parameterTypes,classLoader, args, names);
  AnnotationAwareOrderComparator.sort(instances);
  return instances;
}

可以看到,方法用oadFactoryNames(type, classLoader));通过类型得到所有spring factories的名字,然后根据名字使用createSpringFactoriesInstances创造出实例对象,最后把创建好的对象排序并返回。springfactory是spring-boot-xxx(版本)包里面的META-INF/spring.factories如下 ,然后通过createSpringFactoriesInstances方法利用反射创造出这些实例,实例共四个都是ApplicationContextInitializer的实现类,作用也如下。

# Application Context Initializers
org.springframework.context.ApplicationContextInitializer=\

//为ApplicationContext添加一个能够检查配置,在错误配置时能够打印报错信息的BeanFactoryPostProcessor
org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer,\

//为ApplicationContext设置id
org.springframework.boot.context.ContextIdApplicationContextInitializer,\

//从ApplicationContext的环境配置中,读取Initializer并使用
org.springframework.boot.context.config.DelegatingApplicationContextInitializer,\

//为ApplicationContext设置一个环境变量,方便使用服务器正在监听的端口号。
org.springframework.boot.context.embedded.ServerPortInfoApplicationContextInitializer

(2)初始化监听器   上文中setListeners进行监听器初始化操作,跟初始化context一样,根据类型ApplicationListener.class从spring.factories里找到各种监听器,applicationListener就一个方法onApplicationEvent,用于监听各种事件。

# Application Listeners
org.springframework.context.ApplicationListener=\
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.liquibase.LiquibaseServiceLocatorApplicationListener,\
org.springframework.boot.logging.ClasspathLoggingApplicationListener,\
org.springframework.boot.logging.LoggingApplicationListener

* applicationContext 事件机制    spring的事件机制基于观察者模式,与所有的事件机制都基本类似,他们都需要 事件源, 事件 和事件监听器 组成。只是此处的事件源是ApplicationContext。包括两个重要部分,

ApplicationEvent: 容器事件,必须由 ApplicationContext发布。

    ApplicationListener: 监听器,可有容器中的任何监听器Bean担任。

我们使用时可以定一个event继承ApplicationEvent,然后定一个listener继承ApplicationListener,实现onApplicationEvent方法,在方法里可以根据事件类型判断事件,进行响应处理。事件发布的时候,需要得到ApplicationContext,调用publishEvent(event)进行发布即可。spring也内置了几个事件。

(3)上文的最后,deduceMainApplicationClass方法中,通过获取当前方法调用栈,得到main函数的类,赋值给成员变量。

  

springboot启动过程(1)-初始化的更多相关文章

  1. SpringBoot启动过程原理

    最近这两年springboot突然火起来了,那么我们就来看看springboot的运行原理. 一.springboot的三种启动方式: 1.运行带有main方法的2.通过命令 Java -jar命令3 ...

  2. Spring Boot 学习笔记一(SpringBoot启动过程)

    SpringBoot启动 Spring Boot通常有一个名为*Application的入口类,在入口类里有一个main方法,这个main方法其实就是一个标准的java应用的入口方法. 在main方法 ...

  3. (四)SpringBoot启动过程的分析-预处理ApplicationContext

    -- 以下内容均基于2.1.8.RELEASE版本 紧接着上一篇(三)SpringBoot启动过程的分析-创建应用程序上下文,本文将分析上下文创建完毕之后的下一步操作:预处理上下文容器. 预处理上下文 ...

  4. (三)SpringBoot启动过程的分析-创建应用程序上下文

    -- 以下内容均基于2.1.8.RELEASE版本 紧接着上一篇(二)SpringBoot启动过程的分析-环境信息准备,本文将分析环境准备完毕之后的下一步操作:ApplicationContext的创 ...

  5. (一)SpringBoot启动过程的分析-启动流程概览

    -- 以下内容均基于2.1.8.RELEASE版本 通过粗粒度的分析SpringBoot启动过程中执行的主要操作,可以很容易划分它的大流程,每个流程只关注重要操作为后续深入学习建立一个大纲. 官方示例 ...

  6. (五)SpringBoot启动过程的分析-刷新ApplicationContext

    -- 以下内容均基于2.1.8.RELEASE版本 紧接着上一篇[(四)SpringBoot启动过程的分析-预处理ApplicationContext] (https://www.cnblogs.co ...

  7. SpringBoot启动过程原理(转)

    1.1 Springboot启动: @SpringBootApplication public class ServerApplication { public static void main(St ...

  8. springboot启动过程

    使用了很长时间的springboot了,一直都知道它简单易用,简化了框架的搭建过程,但是还是不知道它是如何启动的,今天就跟着springboot的源码,去探探这其中的奥妙 以下是spring应用的启动 ...

  9. (二)SpringBoot启动过程的分析-环境信息准备

    -- 以下内容均基于2.1.8.RELEASE版本 由上一篇SpringBoot基本启动过程的分析可以发现在run方法内部启动SpringBoot应用时采用多个步骤来实现,本文记录启动的第二个环节:环 ...

随机推荐

  1. git 上传项目到分支

    步骤 git init git add . git commit -m'代码描述' git remote add origin 远程仓库地址 git branch xxx # 创建新分支 git ch ...

  2. javascript测试框架mocha

    node测试框架mocha 简单.灵活.有趣,mocha是一个功能丰富的javascript测试框架,运行在node和浏览器中,使异步测试变得更加简单有趣.http://mochajs.org/ 安装 ...

  3. 解决:在Eclipse中运行monkeyrunner脚本报错: IOError: (2, 'File not found - D:\\workspace\\monkeyrunner_test01 (\u62d2\u7edd\u8bbf\u95ee\u3002)')

    在eclipse中搭建运行monkeyrunner脚本的环境,请见lynnLi的博客monkeyrunner之eclipse中运行monkeyrunner脚本之环境搭建(四) 但在实践中,状况确实层出 ...

  4. ural 2017 Best of a bad lot

    2017. Best of a bad lot Time limit: 1.0 secondMemory limit: 64 MB A cruise liner hasn’t moved away f ...

  5. nyoj-1278-Prototypes analyze(二叉排序树模板)

    题目链接 思路:建树之后,判断有多少种不同的树. 判断不同的树,简单的思路是遍历数组,判断数组后面是否存在一样的树 /* Name:NYOJ-1278-Prototypes analyze Copyr ...

  6. (转)关于Linux核心转储文件 core dump

    所谓核心转储文件是内含进程终止时内存映像的一个文件.产生条件:特定的信号会引发进程创建一个核心转储文件并终止运行. 包括哪些特定信号,请参见http://man7.org/linux/man-page ...

  7. svn 服务器安装包下载地址

    svn 服务器安装包下载地址 https://www.visualsvn.com/server/download/

  8. Windows之IOCP

    IOCP全称I/O Completion Port,中文译为I/O完成端口.IOCP是一个异步I/O的Windows API,它可以高效地将I/O事件通知给应用程序,类似于Linux中的Epoll,关 ...

  9. 洛谷P2606 [ZJOI2010]排列计数

    题目描述 称一个1,2,...,N的排列P1,P2...,Pn是Magic的,当且仅当2<=i<=N时,Pi>Pi/2. 计算1,2,...N的排列中有多少是Magic的,答案可能很 ...

  10. docker容器的服务发现:consul

    官网:https://www.consul.io 官网文档:https://www.consul.io/docs简介 consul是一个服务发现的组件,在docker世界中他比较流行,主要是consu ...