原理:

1-从启动类入口的run方法进入:
public ConfigurableApplicationContext run(String... args) {
-SpringApplicationRunListeners listeners = getRunListeners(args);
-ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);

监听器:EventPublishingRunListener

2-prepareEnvironment方法:

private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners,
ApplicationArguments applicationArguments) {
// Create and configure the environment
ConfigurableEnvironment environment = getOrCreateEnvironment();//用于创建一个存储变量信息的environment
configureEnvironment(environment, applicationArguments.getSourceArgs());
ConfigurationPropertySources.attach(environment);
listeners.environmentPrepared(environment);
bindToSpringApplication(environment);
if (!this.isCustomEnvironment) {
environment = new EnvironmentConverter(getClassLoader()).convertEnvironmentIfNecessary(environment,
deduceEnvironmentClass());
}
ConfigurationPropertySources.attach(environment);
return environment;
}


3-configureEnvironment(environment, applicationArguments.getSourceArgs());加载基本的配置
protected void configureEnvironment(ConfigurableEnvironment environment, String[] args) {
if (this.addConversionService) {
ConversionService conversionService = ApplicationConversionService.getSharedInstance();
environment.setConversionService((ConfigurableConversionService) conversionService);
}
configurePropertySources(environment, args);
configureProfiles(environment, args);
}

加载的配置文件包括下面:

4-prepareEnvironment-中调用listeners.environmentPrepared(environment);
这个监听器就是我们上面的EventPublishingRunListener
继续跟进进出会在EventPublishingRunListner中找到:

@Override
public void environmentPrepared(ConfigurableEnvironment environment) {
this.initialMulticaster
.multicastEvent(new ApplicationEnvironmentPreparedEvent(this.application, this.args, environment));
}//新建事件ApplicationEnvironmentPreparedEvent,

5-寻=寻找监听ApplicationEnvironmentPreparedEvent事件的监听器:ConfigFileApplicationListener
里面有两个个方法

@Override
public void onApplicationEvent(ApplicationEvent event) {
if (event instanceof ApplicationEnvironmentPreparedEvent) {
onApplicationEnvironmentPreparedEvent((ApplicationEnvironmentPreparedEvent) event);
}
if (event instanceof ApplicationPreparedEvent) {
onApplicationPreparedEvent(event);
}
} private void onApplicationEnvironmentPreparedEvent(ApplicationEnvironmentPreparedEvent event) {
List<EnvironmentPostProcessor> postProcessors = loadPostProcessors();
postProcessors.add(this);
AnnotationAwareOrderComparator.sort(postProcessors);
for (EnvironmentPostProcessor postProcessor : postProcessors) {
postProcessor.postProcessEnvironment(event.getEnvironment(), event.getSpringApplication());
}
}
for (EnvironmentPostProcessor postProcessor : postProcessors) {
//对所有实现EnvironmentPostProcessor接口的实现类执行内部方法.postProcessEnvironment
postProcessor.postProcessEnvironment(event.getEnvironment(), event.getSpringApplication());
}

6-官方必须从META-INF/spring.factories:6

在List<EnvironmentPostProcessor> postProcessors = loadPostProcessors();中
List<EnvironmentPostProcessor> loadPostProcessors() {
return SpringFactoriesLoader.loadFactories(EnvironmentPostProcessor.class, getClass().getClassLoader());
} SpringFactoriesLoader的一个静态函数:loadFactories

spring-boot-EnvironmentPostProcessor的更多相关文章

  1. Spring Boot 启动(四) EnvironmentPostProcessor

    Spring Boot 启动(四) EnvironmentPostProcessor Spring 系列目录(https://www.cnblogs.com/binarylei/p/10198698. ...

  2. Spring Boot启动流程详解(一)

    环境 本文基于Spring Boot版本1.3.3, 使用了spring-boot-starter-web. 配置完成后,编写了代码如下: @SpringBootApplication public ...

  3. spring boot容器启动详解

    目录 一.前言 二.容器启动 三.总结 =======正文分割线====== 一.前言 spring cloud大行其道的当下,如果不了解基本原理那么是很纠结的(看见的都是约定大于配置,但是原理呢?为 ...

  4. Spring Boot Application

    spring boot默认已经配置了很多环境变量,例如,tomcat的默认端口是8080,项目的contextpath是“/”等等,spring boot允许你自定义一个application.pro ...

  5. Spring Boot 启动(二) 配置详解

    Spring Boot 启动(二) 配置详解 Spring 系列目录(https://www.cnblogs.com/binarylei/p/10198698.html) Spring Boot 配置 ...

  6. Spring Boot 启动(二) Environment 加载

    Spring Boot 启动(二) Environment 加载 Spring 系列目录(https://www.cnblogs.com/binarylei/p/10198698.html) 上一节中 ...

  7. Spring Boot实现热部署

    在Spring Boot实现代码热部署是一件很简单的事情,代码的修改可以自动部署并重新热启动项目. 引用devtools依赖 <dependency> <groupId>org ...

  8. Spring Boot启动过程及回调接口汇总

    Spring Boot启动过程及回调接口汇总 链接: https://www.itcodemonkey.com/article/1431.html 来自:chanjarster (Daniel Qia ...

  9. spring boot 2.0 源码分析(四)

    在上一章的源码分析里,我们知道了spring boot 2.0中的环境是如何区分普通环境和web环境的,以及如何准备运行时环境和应用上下文的,今天我们继续分析一下run函数接下来又做了那些事情.先把r ...

  10. spring boot 自定义属性覆盖application文件属性

    参考 Spring boot源码分析-ApplicationListener应用环境: https://blog.csdn.net/jamet/article/details/78042486 加载a ...

随机推荐

  1. tomcat编码错乱问题

    问题场景:相同的代码,在同事电脑上可以正常运行,在我电脑上用项目跑代码的时候,密文没法解密,用main方法就可以,而且用同事代码打的war包在我本地也不行,初步排查,应该是本地环境的问题. 场景1:本 ...

  2. “百度杯”CTF比赛 九月场 类型:Web 题目名称:SQLi ---不需要逗号的注入技巧

    今天在i春秋做题的时候遇到了一道非常好的题目,于是在参考了wp的基础上自己复现了一遍,算作一种技巧的学习与收藏吧. 题目i春秋连接:https://www.ichunqiu.com/battalion ...

  3. easyui datagrid中 formatter的用法

    1.基本用法 单元格formatter(格式化器)函数,带3个参数: value:字段值. row:行记录数据. index: 行索引. $('#dg').datagrid({ columns:[[ ...

  4. 计算机网络-IP篇

    目录 IP 基本认识 IP地址 IP 地址的分类 公有 IP 地址与私有 IP 地址 IP 地址与路由控制 IP 分⽚与重组 IPv6 基本认识 IPv4 ⾸部与 IPv6 ⾸部 IP协议 DNS A ...

  5. AcWing 325. 计算机

    传送门 题目大意: 一棵无根树,每条边有一个距离,求每个顶点到距离其最远的顶点的距离. 思路: 考虑树形DP+换根. 令D[x]x到以x为根的子树当中的最长距离,d[x]为次长距离,U[x]为x向上走 ...

  6. (第一章第六部分)TensorFlow框架之实现线性回归小案例

    系列博客链接: (一)TensorFlow框架介绍:https://www.cnblogs.com/kongweisi/p/11038395.html (二)TensorFlow框架之图与Tensor ...

  7. gdb调试快速入门

    编译指令 gcc test.c -o test -g -g是加入调试信息,加入源码信息 启动gdb调试 gdb test 进入gdb中 设置参数 set args 10 20 显示参数show age ...

  8. [USACO20FEB]Equilateral Triangles P 题解

    优雅的暴力. 设三个点为 \((i,j,k)\),则有 \(6\) 个未知数即 \(x_i,x_j,x_k,y_i,y_j,y_k\).又因为有 \(2\) 条关于这 \(6\) 个未知数的方程 \( ...

  9. linux 常用命令:

    查看启动进程命令 ps -ef |  grep donet 1.vi 进入编辑界面 2.ls,ll 查看命令 3.cd 进入命令 4.i 进入插入界面 5. esc 退出编辑界面 6.输入:冒号,进入 ...

  10. QQ密码防盗5招

    第一招:复制粘贴防木马 每次登录QQ前,新建一个文本文件,并键入密码后复制,关闭文本文件后(不要保存)打开QQ,用"Ctrl+V"把密码粘贴到密码栏里,这样可以防范绝大部分的QQ木 ...