SpringBoot外化配置源码解析:命令参数获取文件加载
命令参数的获取命令行参数就是在启动 Spring Boot 项目时通过命令行传递的参数 。 比如 , 用如下命令来启动一个 Spring Boot 的项目 。
java -jar app.jar --name=SpringBoot
那么 , 参数--name=SpringBoot 是如何一 步步传递到 Spring 内部的呢?这就是本节要分析的代码内容 。
默认情况下 , SpringApplication 会将以 上类似 name 的命令行参数(以“”开通)解析封装成一-个 PropertySource 对象 (5.2 节已经具体讲到) , 并将其添加到 Spring-Environment 当中 , 而命令行参数的优先级要高于其他配置源 。
下面 , 我们通过代码来追踪启动过程中整个参数的获取、解析和封装过程 。 首先 , 参数是通过 SpringApplication 的 run 方法的 args 参数来传递的 。
在 SpringApplication 的 run 方 法 中,通 过 以 下 操 作 先 将 args 封 装 于 对 象ApplicationArguments 中 , 然后又将封装之后的对象传递入 prepareEnvironment 方法 。
public ConfigurableApplicationContext run(String... args) {ApplicationArguments applicationArguments = new DefaultApplicat ionArgu-ments(args);ConfigurableEnvironment environment = prepareEnvironment(listeners,applicationArguments);} catch (Throwable ex) {}}
在 prepareEnvironment 方法中通过 applicationArguments. getSourceArgs()获得传递的参数数组 , 并作为参数调用 configureEnvironment 方法 , 此处获得的 args 依旧是未解析的参数值 , 代码如下 。
private ConfigurableEnvironment prepareEnvironment (SpringApplicationRunL isteners listeners,ApplicationArguments applicationArguments) {configureEnvironment (environment, applicationArguments . getSourceArgs());}在 configureEnvironment 方法中又将参数传递给 configurePropertySources 方法 。 protected void configureEnvironment (ConfigurableEnvironment environment,String[] args) {configurePropertySources(environment, args);}}
而在 configurePropertySources 方法中才对参数进行了真正的解析和封装 。
protected void configurePropertySources(ConfigurableEnvironment environmeString[]args) {//获得环境中的属性资源信息MutablePropertySources sources = environment . getPropertySources();//如果默认属性配置存在 , 则将其放置在属性资源的最后位置if (this. defaultProperties != null //如果命令行属性未被禁用且存在if (this . addCommandL ineProperties //如果默礼属性资源中不包含该命令则将命令行属性放置在第一位//如果包含则通过 Compos itePropertySource 进行处理if (sources . contains(name)) {PropertySource> source = sources . get(name);CompositePropertySource composite = new CompositePropertySource(name);composite . addPropertySource (new SimpleCommandL inePropertySource("springApplicationCommandL ineArgs", args));composite . addPropertySource(source);sources . replace(name, composite);} else|/不存在 , 则添加并放置在第一位sources . addFirst(new SimpleCommandL inePropertySource(args));}
configurePropertySources 方法在之前章节中有过讲解 , 下面针对命令行参数再次进行讲解和深入分析 , 重点介绍两个内容:参数的优先级和命令行参数的解析 。
先说参数的优先级 , 从上面的代码注解中可以看到 , configurePropertySources 方法第一步获得环境变量中存储配置信息的
sources;第二步判断默认参数是否为空 , 如果不为空 , 则将默认参数放置在 sources 的最后位置 , 这里已经明显反映了参数的优先级是通过顺序来体现的;第三步 , 如果命令参数未被禁用 , 且不为空 , 则要么将原有默认参数替换掉 , 要么直接放在第一位 , 这-一步中的替换操作也是另外一种优先级形式的体现 。
顺便提一下 ,在上面的代码中 , addCommandL ineProperties 参数是可以进行设置的 , 当不允许使用命令行参数时 , 可以通过 SpringApplication 的 setAddCommandLineProperties方法将其设置为 false 来禁用 。
命令行参数的解析用到了 SimpleCommandLinePropertySource 类 , 而该类的相关使用在上一节中已经详细介绍了 。
通过上面一系列的代码追踪 , 我们了解了通过命令传递的参数是如何一步步被封装入 Spring的 Environment 当中的 。 下一 节 , 我们将分析配置文件中的参数获取 。
文章插图
配置文件的加载Spring Boot 启动时默认会加载 classpath 下的 application.yml 或 application.properties 文件 。 配置文件的加载过程主要是利用 Spring Boot 的事件机制来完成的 , 也就是我们之前章节所讲到的 SpringApplicationRunL isteners 中的 environmentPrepared 方法来启动加载配置文件的事件 。 通过该方法发布的事件会被注册的 ConfigFileApplicationListener 监听到 , 从而实现资源的加载 。
- 芯片|华米GTS2mini和红米手表哪个好 参数功能配置对比
- 曝光|OPPO新机曝光,配置强悍颜值动人,“三金影后”为其代言
- 曝光|诺基亚新机定价、配置曝光:4GB/64GB成标配,最低售价1685元
- 一流|妥妥的一流旗舰配置,vivo X系列新机已手握两大“杀器”
- 感人|千元5G手机做成这样了!realmeQ2配置感人诚意满满
- 水桶|红米note9再续神话!价格便宜配置丰富,这才是真正的水桶机
- OPPO将抢发骁龙875芯片!配置强悍:小米11或无缘首发
- 华为P50外观配置全曝光!新5G芯片+歪镜头设计:售价很感人
- R2|「集微拆评」坚果R2评测:旗舰配置加独有功能,手机更好用了
- linux配置nginx定时日志分割