SpringBoot运行流程源码分析

阅读: 评论:0

SpringBoot运行流程源码分析

SpringBoot运行流程源码分析

Spring Boot外化配置源码解析

外化配置简介

Spring Boot设计了非常特殊的加载指定属性文件(PropertySouce)的顺序,允许属性值合理的覆盖,属性值会以下面的优先级进行配置。
  • home目录下的Devtool全局设置属性(~/.spring-boot-devtools.properties,条件是当devtools激活时)
  • @TestPropertySource注解的测试用例。
  • @SpringBootTest#properties注解的测试用例。
  • 命令行参数。
  • 来自SPRING_APPLICATION_JSON的属性(内嵌在环境变量或系统属性中的内联JSON)
  • ServletConfig初始化参数
  • ServletContext初始化参数
  • java:comp/env的JNDI属性
  • Java系统属性(Properties())
  • 操作系统环境变量
  • RandomValuePropertySource,只包含random.*中的属性
  • jar包外的Profile_specific应用属性(application-{profile}.propertis和YAML变量)
  • jar包内的Profile_specific应用属性(application-{profile}.propertis和YAML变量)
  • jar包外的应用配置(application.properties和YAML变量)
  • jar包内的应用配置(application.properties和YAML变量)
  • @Configuration类上的@PropertySource注解
  • 默认属性(通过SpringApplication.setDefaultProperties指定)

在以上配置方式中,我们经常使用的包括:命令参数,属性文件,YAML文件等内容,以下将围绕他们的运行及相关代码进行讲解。

ApplicationArguments参数处理

ApplicationArguments提供了针对参数的解析和查询功能。在Spring Boot运行阶段的章节中我们提到过,通过SpringApplication.run(args)传递的参数会被封装在ApplicationArguments接口中。本节我们来详细了解下ApplicationArguments接口。
接口定义及初始化

首先看一下ApplicationArguments接口的具体方法定义及功能介绍。

package org.springframework.boot;import java.util.List;
import java.util.Set;public interface ApplicationArguments {//返回原始未处理的参数(通过application传入的)String[] getSourceArgs();//返回所有参数的集合,如参数为:--foo=bar --debug,则返回【"foo","debug"】Set<String> getOptionNames();//选项参数中是否包含指定名称的参数boolean containsOption(String name);//根据选项参数的名称获取选项参数的值列表List<String> getOptionValues(String name);//返回非选项参数列表List<String> getNonOptionArgs();}

通过接口定义可以看出,ApplicationArguments主要提供了针对参数名称和值的查询,以及判断是否存在指定参数的功能。

在Spring Boot的初始化运行过程中,ApplicationArguments接口的实例化操作默认是通过实现类DefaultApplicationArguments来完成的。DefaultApplicationArguments的底层又是基于Spring框架中的命令行配置源SimpleCommandLinePropertySource实现的,SpringCommandLinePropertySource是PropertySource抽象类的派生类。

以下代码中内部类Source便是SimppleCommandLinePropertySource的子类。

public class DefaultApplicationArguments implements ApplicationArguments {private final Source source;private final String[] args;public  args) {Null(args, "Args must not be null");this.source = new Source(args);this.args = args;}......private static class Source extends SimpleCommandLinePropertySource {......}}

我们再来看SimpleCommandLinePropertySource的构造方法,通过代码会发现默认使用spring的SimpleCommandLineArgsParser对args参加进行解析。

public class SimpleCommandLinePropertySource extends CommandLinePropertySource<CommandLineArgs> {public  args) {super((new SimpleCommandLineArgsParser()).parse(args));}//重载的构造方法public SimpleCommandLinePropertySource(String name, String[] args) {super(name, (new SimpleCommandLineArgsParser()).parse(args));}......
}

除了构造方法之外,SimpleCommandLinePropertySource还提供了不同类型参数信息的获取和检查是否存在的功能,代码如下:

public class SimpleCommandLinePropertySource extends CommandLinePropertySource<CommandLineArgs> {......//获取选项参数数组    public String[] getPropertyNames() {StringArray(((CommandLineArgs)this.source).getOptionNames());}//获取是否包含指定name的参数protected boolean containsOption(String name) {return ((CommandLineArgs)this.source).containsOption(name);}//获取指定name的选项参数列表@Nullableprotected List<String> getOptionValues(String name) {return ((CommandLineArgs)this.source).getOptionValues(name);}//获取非选项参数列表protected List<String> getNonOptionArgs() {return ((CommandLineArgs)this.source).getNonOptionArgs();}
}

ApplicatinArguments,或者更进一步说是SimpleCommandLinePropertySource对参数类型是有所区分的,即选项参数和非选项参数。

选项参数必须以“–”为前缀,参数值可为空,该参数可以通过Spring Boot属性处理后使用,比如在执行jar -jar命令时,添加选项参数“–app.name=spring boot start",在代码中可以通过注解@Value属性及其他方式获取到该参数的值。该参数可以通过逗号分隔多个参数值,或者多次使用同一个参数来包含多个参数的值。

非选项参数并不要求以“–”前缀开始,可自行定义。非选项参数可以直接在jar -jar命令中定义参数为“non-option"的参数值。

以上所说的选项参数和非选项参数的解析是在SimpleCommandLinePropertySource构造方法中调用SimpleCommandLineArgsParser中完成的,代码如下:

class SimpleCommandLineArgsParser {SimpleCommandLineArgsParser() {}//解析args参数,返回一个完整的CommandLineArgs对象public CommandLineArgs  args) {CommandLineArgs commandLineArgs = new CommandLineArgs();String[] var3 = args;int var4 = args.length;//遍历参数for(int var5 = 0; var5 < var4; ++var5) {String arg = var3[var5];//解析选项参数,以"--"开头if (arg.startsWith("--")) {String optionText = arg.substring(2, arg.length());String optionValue = null;String optionName;//判断是--foo=bar参数格式,还是-foo参数格式,并分别处理获取值if (ains("=")) {optionName = optionText.substring(0, optionText.indexOf(61));optionValue = optionText.substring(optionText.indexOf(61) + 1

本文发布于:2024-01-29 00:34:18,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170645966311437.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:源码   流程   SpringBoot
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23