SpringBoot基础-Environment解析

本文深入解析SpringBoot的Environment,从实现EnvironmentAware和CommandLineRunner接口入手,跟踪getProperty源码,揭示属性如何从PropertySources中读取。接着详细分析prepareEnvironment过程,包括getOrCreateEnvironment、configureEnvironment等步骤,探讨不同阶段属性的加载和定制,如默认属性、命令行参数、配置文件等。
摘要由CSDN通过智能技术生成

获取属性源码跟踪解析

入口方法

@Component
public class EnvironmentDebugger implements CommandLineRunner, EnvironmentAware {
   

    private Environment environment;

    @Override
    public void run(String... args) throws Exception {
   
        String study2 = environment.getProperty("study2");
    }

    @Override
    public void setEnvironment(Environment environment) {
   
        this.environment = environment;
    }
}

实现EnvironmentAware 接口,获取Environment对象
实现CommandLineRunner接口,在容器启动完成后,获取key的值,作为源码跟踪的入口

源码跟踪

根据入口environment.getProperty,一直点进入org.springframework.core.env.PropertySourcesPropertyResolver#getProperty(java.lang.String, java.lang.Class, boolean),可以看到最基础的实现

@Nullable
protected <T> T getProperty(String key, Class<T> targetValueType, boolean resolveNestedPlaceholders) {
   
	if (this.propertySources != null) {
   
		for (PropertySource<?> propertySource : this.propertySources) {
   
			if (logger.isTraceEnabled()) {
   
				logger.trace("Searching for key '" + key + "' in PropertySource '" +
						propertySource.getName() + "'");
			}
			Object value = propertySource.getProperty(key);
			if (value != null) {
   
				if (resolveNestedPlaceholders && value instanceof String) {
   
					value = resolveNestedPlaceholders((String) value);
				}
				logKeyFound(key, propertySource, value);
				return convertValueIfNecessary(value, targetValueType);
			}
		}
	}
	if (logger.isTraceEnabled()) {
   
		logger.trace("Could not find key '" + key + "' in any property source");
	}
	return null;
}

方法中可以看出通过key获取属性值,遍历propertySources中存放的PropertySource,并且从中依次取出属性,如果所有都没有取到,则返回NULL

在这里插入图片描述
可以看出propertySources中共存在7中类型的属性,可以找到我们设置的默认属性,并且已键值对存放数据

PropertySource源码

public abstract class PropertySource<T> {
   

	protected final Log logger = LogFactory.getLog(getClass());

	protected final String name;

	protected final T source;
}

source为存放属性的具体实现

通过获取属性可以看出所有的属性都存放在:propertySources中,只需要搞懂spring容器在启动的时候是如何装载自定义的属性进propertySources就可以

Environment加载属性

入口函数

springApplication.run(args) --> prepareEnvironment

prepareEnvironment

private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners,
		DefaultBootstrapContext bootstrapContext, ApplicationArguments applicationArguments) {
   
	// Create and configure the environment
	ConfigurableEnvironment environment = getOrCreateEnvironment();
	configureEnvironment(environment, applicationArguments.getSourceArgs());
	ConfigurationPropertySources.attach(environment);
	listeners.environmentPrepared(bootstrapContext, environment);
	DefaultPropertiesPropertySource.moveToEnd(environment);
	configureAdditionalProfiles(environment);
	bindToSpringApplication(environment);
	if (!this.isCustomEnvironment) {
   
		environment = new EnvironmentConverter(getClassLoader()).convertEnvironmentIfNecessary(environment,
				deduceEnvironmentClass());
	}
	ConfigurationPropertySources.attach(environment);
	return environment;
}

在prepareEnvironment中,共进行了一下的进步操作:

  1. 创建Environment对象:getOrCreateEnvironment()
  2. 配置属性:configureEnvironment()
  3. 添加configurationProperties属性:ConfigurationPropertySources.attach(environment)
  4. 通过事件发布器发布environment事件:listeners.environmentPrepared(bootstrapContext, environment);
  5. 将defaultProperties属性移到最后面,因为是默认,所有在后面兜底:DefaultPropertiesPropertySource.moveToEnd(environment)
  6. 加载profile配置文件属性:configureAdditionalProfiles(environ
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值