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<ApplicationEnvironmentPreparedEvent> {
@Override
public void onApplicationEvent(ApplicationEnvironmentPreparedEvent applicationEnvironmentPreparedEvent) {
ConfigurableEnvironment environment = applicationEnvironmentPreparedEvent.getEnvironment();
MutablePropertySources mutablePropertySources = environment.getPropertySources();
Map<String, Object> 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 配置信息时使用。