springboot启动过程(1)-初始化
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)-初始化的更多相关文章
- SpringBoot启动过程原理
最近这两年springboot突然火起来了,那么我们就来看看springboot的运行原理. 一.springboot的三种启动方式: 1.运行带有main方法的2.通过命令 Java -jar命令3 ...
- Spring Boot 学习笔记一(SpringBoot启动过程)
SpringBoot启动 Spring Boot通常有一个名为*Application的入口类,在入口类里有一个main方法,这个main方法其实就是一个标准的java应用的入口方法. 在main方法 ...
- (四)SpringBoot启动过程的分析-预处理ApplicationContext
-- 以下内容均基于2.1.8.RELEASE版本 紧接着上一篇(三)SpringBoot启动过程的分析-创建应用程序上下文,本文将分析上下文创建完毕之后的下一步操作:预处理上下文容器. 预处理上下文 ...
- (三)SpringBoot启动过程的分析-创建应用程序上下文
-- 以下内容均基于2.1.8.RELEASE版本 紧接着上一篇(二)SpringBoot启动过程的分析-环境信息准备,本文将分析环境准备完毕之后的下一步操作:ApplicationContext的创 ...
- (一)SpringBoot启动过程的分析-启动流程概览
-- 以下内容均基于2.1.8.RELEASE版本 通过粗粒度的分析SpringBoot启动过程中执行的主要操作,可以很容易划分它的大流程,每个流程只关注重要操作为后续深入学习建立一个大纲. 官方示例 ...
- (五)SpringBoot启动过程的分析-刷新ApplicationContext
-- 以下内容均基于2.1.8.RELEASE版本 紧接着上一篇[(四)SpringBoot启动过程的分析-预处理ApplicationContext] (https://www.cnblogs.co ...
- SpringBoot启动过程原理(转)
1.1 Springboot启动: @SpringBootApplication public class ServerApplication { public static void main(St ...
- springboot启动过程
使用了很长时间的springboot了,一直都知道它简单易用,简化了框架的搭建过程,但是还是不知道它是如何启动的,今天就跟着springboot的源码,去探探这其中的奥妙 以下是spring应用的启动 ...
- (二)SpringBoot启动过程的分析-环境信息准备
-- 以下内容均基于2.1.8.RELEASE版本 由上一篇SpringBoot基本启动过程的分析可以发现在run方法内部启动SpringBoot应用时采用多个步骤来实现,本文记录启动的第二个环节:环 ...
随机推荐
- 2017-03-04 dotnet core网站发布到Linux系统中
今天开始学习dotnet core的开发,距离Visual Stuio 2017正式版的发布,也就是VS20周岁的生日还有三天,在我的电脑上安装的是VS2017 Enterprise RC版, 在VS ...
- 解决:cmd中运行monkeyrunner monkey_recorder.py报错: Can't open specified script file
看lynnLi的博客monkeyrunner之录制与回放(七),遇到了一个问题,我在cmd中输入monkeyrunner monkey_recorder.py,却报错了: 当时第一个感觉时,先到\sd ...
- NSLog Release
//将下面的代码插入到pch文件中即可 #ifndef __OPTIMIZE__ # define NSLog(…) NSLog(__VA_ARGS__) #else # define NSLog(… ...
- eclipse 创建 maven web工程
填写完点finish,创建成功 接着找到工作空间创建的这个项目,.settings文件夹下修改两个文件 改为自己的java版本,我的是1.8 将项目改为动态3.0 此时项目还没有web.xml,接下来 ...
- New Concept English three (57)
28w/m 54errors I stopped to let the car cool off and to study the map. I had expected to be near my ...
- Codeforces Round #281 (Div. 2) A. Vasya and Football(模拟)
简单题,却犯了两个错误导致WA了多次. 第一是程序容错性不好,没有考虑到输入数据中可能给实际已经罚下场的人再来牌,这种情况在system测试数据里是有的... 二是chronologically这个词 ...
- web端测试小知识
1.测试web端会看请求.数据.定位问题 在浏览器中按F12按钮,然后继续操作 一个操作有时请求很多个接口,点击“preview”,查看返回的数据 ========================== ...
- git 远程库 创建私钥
1.创建SSH Key.在用户主目录下,看看有没有.ssh目录,如果有,再看看这个目录下有没有id_rsa和id_rsa.pub这两个文件,如果已经有了,可直接跳到下一步.如果没有,打开Shell(W ...
- stl_algobase.h
stl_algobase.h // Filename: stl_algobase.h // Comment By: 凝霜 // E-mail: mdl2009@vip.qq.com // Blog: ...
- 2017-2018-1 20179215《Linux内核原理与分析》第十二周作业
Sql注入基础原理介绍 分组:和20179205王雅哲共同完成实验 一.实验说明 1.1 sql注入 SQL注入攻击通过构建特殊的输入作为参数传入Web应用程序,而这些输入大都是SQL语法里的一些组 ...