SpringBoot-外部化配置原理分析

SpringBoot 加载配置文件的源码分析

public static void main(String[] args) {
    SpringApplication.run(SpringBootConfigApplication.class, args);
}
public ConfigurableApplicationContext run(String... args) {}
// spring 通过 SpringFactoriesLoader 加载文件 META-INF/spring.factories 中的类
SpringApplicationRunListeners listeners = getRunListeners(args);
// 在创建 Spring 上下文之前,先准备 Spring 上下文中所需要的配置信息,通过监听器监听事件加载配置文件
ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
// ConfigFileApplicationListener 监听器的回调方法
public void onApplicationEvent(ApplicationEvent event) {
    if (event instanceof ApplicationEnvironmentPreparedEvent) {
        onApplicationEnvironmentPreparedEvent((ApplicationEnvironmentPreparedEvent) event);
    }
    if (event instanceof ApplicationPreparedEvent) {
        onApplicationPreparedEvent(event);
    }
}
// 通过 PropertySourceLoader 加载配置文件
// PropertySourceLoader 的实现类有 YamlPropertySourceLoader 和 PropertiesPropertySourceLoader 分别加载 yaml 文件和 xml 文件

public static void fillProperties(Properties props, Resource resource) throws IOException {
    InputStream is = resource.getInputStream();
    try {
        String filename = resource.getFilename();
        if (filename != null && filename.endsWith(XML_FILE_EXTENSION)) {
            props.loadFromXML(is);
        }
        else {
            props.load(is);
        }
    }
    finally {
        is.close();
    }
}

通过上面的源码分析,知道 SpringBoot 是通过监听器监听 ApplicationEnvironmentPreparedEvent 事件进行加载配置文件的,所以我们也自定义自己的监听器去加载任何地方的配置文件

// 此类要配置在 META-INF/spring.factories
public class CustomizerSpringApplicationRunListeners
        implements ApplicationListener {

    @Override
    public void onApplicationEvent(ApplicationEnvironmentPreparedEvent applicationEnvironmentPreparedEvent) {
        ConfigurableEnvironment environment = applicationEnvironmentPreparedEvent.getEnvironment();
        MutablePropertySources mutablePropertySources = environment.getPropertySources();
        Map map = new HashMap<>();
        map.put("name", "自定义");
        map.put("age", "30");
        MapPropertySource mapPropertySource = new MapPropertySource("abc", map);
        mutablePropertySources.addFirst(mapPropertySource);
    }
}
通过 http://localhost:8080/actuator/env 查看配置信息是否加载到了上下文环境中

ConfigurationProperties的使用

注解实体类,映射 properties 文件中的配置信息到实体类中,使用时通过 @Autowire 注入实体类即可获取配置信息。一般用于加载 jdbc、redis 配置信息时使用。

你可能感兴趣的:(SpringBoot)