SpringBoot源码解析(十)prepareEnvironment收尾

最近很多篇都是围绕prepareEnvironment方法在分析,上篇补充了ApplicationEnvironmentPreparedEvent事件的处理,相当于下面的listeners.environmentPrepared方法就分析完了,本文就把这个方法中剩下的几行代码收下尾
在这里插入图片描述
先看第一行bindToSpringApplication

    protected void bindToSpringApplication(ConfigurableEnvironment environment) {
        try {
            Binder.get(environment).bind("spring.main", Bindable.ofInstance(this));
        } catch (Exception var3) {
            throw new IllegalStateException("Cannot bind to SpringApplication", var3);
        }
    }

Binder是SpringBoot 2.X引入的新特性,用于将environment的属性绑定到目标类上
这里就相当于将spring.main开头的属性,绑定到SpringApplicaiton对象上,前提是SpringApplication提供了相应属性的set方法
比如常见的配置spring.main.allow-bean-definition-overriding=true,SpringApplication类存在该属性,且有对应的set方法,那么就会将配置文件中的值赋给该属性

public class SpringApplication {
	......
	private boolean allowBeanDefinitionOverriding;
	......
	......
	public void setAllowBeanDefinitionOverriding(boolean allowBeanDefinitionOverriding) {
        this.allowBeanDefinitionOverriding = allowBeanDefinitionOverriding;
    }
    ......

继续下一行

    if (!this.isCustomEnvironment) {
        environment = (new EnvironmentConverter(this.getClassLoader())).convertEnvironmentIfNecessary((ConfigurableEnvironment)environment, this.deduceEnvironmentClass());
    }

isCustomEnvironment属性在SpringApplication的构造函数中初始化为false,所以会进if,它的作用就是对environment的类型做个校正
deduceEnvironmentClass方法根据应用类型推断environment应该是哪个实现类

    private Class<? extends StandardEnvironment> deduceEnvironmentClass() {
        switch(this.webApplicationType) {
        case SERVLET:
            return StandardServletEnvironment.class;
        case REACTIVE:
            return StandardReactiveWebEnvironment.class;
        default:
            return StandardEnvironment.class;
        }
    }

我们创建的时候就是根据应用类型创建的,也没修改过,所以convertEnvironmentIfNecessary方法中判断类型是一致的,不需要做转型

    StandardEnvironment convertEnvironmentIfNecessary(ConfigurableEnvironment environment, Class<? extends StandardEnvironment> type) {
        return type.equals(environment.getClass()) ? (StandardEnvironment)environment : this.convertEnvironment(environment, type);
    }

最后一行ConfigurationPropertySources.attach方法

    public static void attach(Environment environment) {
        Assert.isInstanceOf(ConfigurableEnvironment.class, environment);
        MutablePropertySources sources = ((ConfigurableEnvironment)environment).getPropertySources();
        PropertySource<?> attached = sources.get("configurationProperties");
        if (attached != null && attached.getSource() != sources) {
            sources.remove("configurationProperties");
            attached = null;
        }

        if (attached == null) {
            sources.addFirst(new ConfigurationPropertySourcesPropertySource("configurationProperties", new SpringConfigurationPropertySources(sources)));
        }

    }

它先从environment中取出了所有的PropertySource,然后用这些配置构造了一个名为configurationProperties的配置项,添加到PropertySource列表的最前面,也就是赋予了最高的优先级
其具体类型为ConfigurationPropertySourcesPropertySource

class ConfigurationPropertySourcesPropertySource extends PropertySource<Iterable<ConfigurationPropertySource>> implements OriginLookup<String> {

从泛型参数可知,它存储的是一个PropertySource列表的迭代器,也就是说这个新的PropertySource持有了所有environment中其它PropertySource的引用,本身并没有额外的信息,如果将来有其它组件需要使用配置信息,那么只需要将它暴露出去就行了,屏蔽了底层不同PropertySource的细节

至此run方法里的这行prepareEnvironment方法就结束了,终于可以回到run方法的主干了…
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值