springboot源码剖析(三) 环境配置

  概念

           springboot在启动流程中会把环境配置都加载进应用当中。


  实现原理

          使用环境配置器用来加载和解析所有配置文件。配置文件会被抽象成PropertySource对象存储。

     uml类图

     环境配置流程

 


  源码剖析  

           环境配置

/** SpringApplication.class 环境配置 **/
// 配置入口
public ConfigurableApplicationContext run(String... args) {
    // ...
    // 解析命令行参数
     ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
    // ★解析配置文件
    ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
    // ...
}
// 解析配置文件
private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments) {
    // 1.获取环境配置器
    ConfigurableEnvironment environment = this.getOrCreateEnvironment();
    // ★2.环境配置器配置
    this.configureEnvironment((ConfigurableEnvironment)environment, applicationArguments.getSourceArgs());
    // 环境配置器配置文件列表加ConfigurationPropertySources类
    ConfigurationPropertySources.attach((Environment)environment);
    // ★3.事件发布器:通知监听者环境准备好了(监听者主要是加配置文件)
    // 其中ConfigFileApplicationListener加载了yml文件和中间件的配置
    listeners.environmentPrepared((ConfigurableEnvironment)environment);
    // 4.spring类绑定source属性(我的没绑到符合的)
    this.bindToSpringApplication((ConfigurableEnvironment)environment);
    // 5.不标准的环境配置器类会被强转成标准类
    if (!this.isCustomEnvironment) {
        environment = (new EnvironmentConverter(this.getClassLoader())).convertEnvironmentIfNecessary((ConfigurableEnvironment)environment, this.deduceEnvironmentClass());
    }
    // 6.绑定source属性
    ConfigurationPropertySources.attach((Environment)environment);
    return (ConfigurableEnvironment)environment;
}
// 1.获取环境配置器
private ConfigurableEnvironment getOrCreateEnvironment() {
    if (this.environment != null) {
        return this.environment;
    } else {
        // 由web应用类型决定,服务器是StandardServletEnvironment类
        switch(this.webApplicationType) {
        case SERVLET:
            // 服务器为StandardServletEnvironment,构造会初始化资源解析器和读取定制化配置文件
            return new StandardServletEnvironment();
        case REACTIVE:
            return new StandardReactiveWebEnvironment();
        default:
            return new StandardEnvironment();
        }
    }
}
// 2.环境配置器配置
protected void configureEnvironment(ConfigurableEnvironment environment, String[] args) {
    // 给环境配置器的资源解析器设置转换服务
    if (this.addConversionService) {
        ConversionService conversionService = ApplicationConversionService.getSharedInstance();
        environment.setConversionService((ConfigurableConversionService)conversionService);
    }
    // 命令行参数添加到配置文件列表
    this.configurePropertySources(environment, args);
    // 设置动态开发环境
    this.configureProfiles(environment, args);
}

  环境配置器

/** StandardServletEnvironment.class 环境配置器 */
public class StandardServletEnvironment extends StandardEnvironment implements ConfigurableWebEnvironment {
    // 定制配置文件加载
    protected void customizePropertySources(MutablePropertySources propertySources) {
        propertySources.addLast(new StubPropertySource("servletConfigInitParams"));
        propertySources.addLast(new StubPropertySource("servletContextInitParams"));
        if (JndiLocatorDelegate.isDefaultJndiEnvironmentAvailable()) {
            propertySources.addLast(new JndiPropertySource("jndiProperties"));
        }
    
        super.customizePropertySources(propertySources);
    }
}
/** AbstractEnvironment.class 环境配置器基类 */
public abstract class AbstractEnvironment implements ConfigurableEnvironment {
    public static final String IGNORE_GETENV_PROPERTY_NAME = "spring.getenv.ignore";
    public static final String ACTIVE_PROFILES_PROPERTY_NAME = "spring.profiles.active";
    public static final String DEFAULT_PROFILES_PROPERTY_NAME = "spring.profiles.default";
    protected static final String RESERVED_DEFAULT_PROFILE_NAME = "default";
    protected final Log logger = LogFactory.getLog(this.getClass());
    // 动态开发环境
    private final Set<String> activeProfiles = new LinkedHashSet();
    // 默认开发环境
    private final Set<String> defaultProfiles = new LinkedHashSet(this.getReservedDefaultProfiles());
    // 配置文件列表
    private final MutablePropertySources propertySources = new MutablePropertySources();
    // 资源解析器
    private final ConfigurablePropertyResolver propertyResolver;
    // 构造:实例化一个资源解析器,将定制化资源加载到配置文件列表中
    public AbstractEnvironment() {
        this.propertyResolver = new PropertySourcesPropertyResolver(this.propertySources);
        this.customizePropertySources(this.propertySources);
    }
}       
/** MutablePropertySources.class 配置文件列表 */
public class MutablePropertySources implements PropertySources {
    // 配置文件都会被抽象成对象放在这里
    private final List<PropertySource<?>> propertySourceList;
}

 

      

posted @ 2022-10-30 16:18  Duikerdd  阅读(186)  评论(0编辑  收藏  举报