一、配置加载
public static void main(String[] args) { ConfigurableApplicationContext ctx = SpringApplication.run(SampleTomcatApplication.class, args); String foo = ctx.getEnvironment().getProperty("foo"); System.out.println(foo); }
打印结果
aaa,bbb
源码解析
1、我们在idea环境配置的参数Program arguments上配置的参数,就会被传进main方法的args中
//封装命令行参数 ApplicationArguments applicationArguments = new DefaultApplicationArguments(args); public DefaultApplicationArguments(String... args) { Assert.notNull(args, "Args must not be null"); this.source = new Source(args); this.args = args; } Source(String[] args) { super(args); } public SimpleCommandLinePropertySource(String... args) { super(new SimpleCommandLineArgsParser().parse(args)); } //解析命令行参数 public CommandLineArgs parse(String... args) { CommandLineArgs commandLineArgs = new CommandLineArgs(); for (String arg : args) { //固定格式 if (arg.startsWith("--")) { String optionText = arg.substring(2); String optionName; String optionValue = null; int indexOfEqualsSign = optionText.indexOf('='); if (indexOfEqualsSign > -1) { optionName = optionText.substring(0, indexOfEqualsSign); optionValue = optionText.substring(indexOfEqualsSign + 1); } else { optionName = optionText; } if (optionName.isEmpty()) { throw new IllegalArgumentException("Invalid argument syntax: " + arg); } commandLineArgs.addOptionArg(optionName, optionValue); } else { commandLineArgs.addNonOptionArg(arg); } } return commandLineArgs; }
解析完命令行参数,最终放入到了PropertySource的source属性中,代码就不放了
2、构建环境
ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
//创建并配置相应的环境,获取对应的ConfigurableEnvironment ConfigurableEnvironment environment = getOrCreateEnvironment(); //根据用户配置,配置 environment系统环境 configureEnvironment(environment, applicationArguments.getSourceArgs());
创建环境
//根据环境创建对应ConfigurableEnvironment private ConfigurableEnvironment getOrCreateEnvironment() { if (this.environment != null) { return this.environment; } switch (this.webApplicationType) { case SERVLET://Web程序 return new StandardServletEnvironment(); case REACTIVE://响应式web环境 return new StandardReactiveWebEnvironment(); default://普通程序 return new StandardEnvironment(); } }
都继承自AbstractEnvironment
public abstract class AbstractEnvironment implements ConfigurableEnvironment { //初始化配置文件source对象 private final MutablePropertySources propertySources = new MutablePropertySources(); //初始化了配置文件解析器 private final ConfigurablePropertyResolver propertyResolver = new PropertySourcesPropertyResolver(this.propertySources); ··· }
解析配置文件,并配置到环境中
protected void configureEnvironment(ConfigurableEnvironment environment, String[] args) { if (this.addConversionService) { ConversionService conversionService = ApplicationConversionService.getSharedInstance(); environment.setConversionService((ConfigurableConversionService) conversionService); } // 将main 函数的args封装成 SimpleCommandLinePropertySource 加入environment中。 configurePropertySources(environment, args); // 激活相应的配置文件 configureProfiles(environment, args); } protected void configurePropertySources(ConfigurableEnvironment environment, String[] args) { MutablePropertySources sources = environment.getPropertySources(); if (this.defaultProperties != null && !this.defaultProperties.isEmpty()) { sources.addLast(new MapPropertySource("defaultProperties", this.defaultProperties)); } if (this.addCommandLineProperties && args.length > 0) { String name = CommandLinePropertySource.COMMAND_LINE_PROPERTY_SOURCE_NAME; if (sources.contains(name)) { PropertySource<?> source = sources.get(name); CompositePropertySource composite = new CompositePropertySource(name); //解析args,并设置到source属性中,SimpleCommandLinePropertySource继承自PropertySource composite.addPropertySource( new SimpleCommandLinePropertySource("springApplicationCommandLineArgs", args)); composite.addPropertySource(source); //存在覆盖的参数,则替换 sources.replace(name, composite); } else { //解析并设置参数到环境中 sources.addFirst(new SimpleCommandLinePropertySource(args)); } } }
获取配置文件属性String foo = ctx.getEnvironment().getProperty("foo");
public String getProperty(String key) { return this.propertyResolver.getProperty(key); }
走的就是AbstractEnvironment方法,通过ConfigurablePropertyResolver的方法获取,具体获取源码也不看了。
二、热部署
jar包依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> </dependency>