大家好!用過spring boot的人應該都知道“application.properties”和“application.yml”這兩個配置文件吧,最常見的就是在這兩個文件裏面配置數據庫連接信息。那麼,今天我要向大家揭祕,spring boot是何時加載它們,以及如何應用配置文件的過程。
一. 何時加載application.*
spring boot的啓動是由SpringApplication負責的,其中有一個很重要的run(String... args)方法。在run方法中有一個步驟是預準備環境對象,即ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners, ApplicationArguments)方法。該方法會通知所有已註冊的事件監聽器(ApplicationListener),通知它們環境對象(Environment)已經創建了,可以爲它添加屬性源(PropertySource)了。對於Environment沒有概念的朋友,可以看我之前的博客。
配置文件事件監聽器(ConfigFileApplicationListener)收到這個通知後做出迴應,就把"application.properties"和"application.yml"中的內容轉換成屬性源添加到環境對象。那麼,配置文件事件監聽器又是從哪冒出來的呢?它被配置在autoconfigure's jar包裏的spring.factories文件中,很多跟boot相關的jar包裏都包含這個文件。在執行run(String... args)之前,spring就已把這個事件監聽器註冊到bean工廠(BeanFactory)。
二. 把application.*中的配置數據輸送到哪些對象呢?
把配置數據輸送到被@ConfigurationProperties註解的類,這些類的類名往往是這樣的“xxxxxxProperties ”,比如“WebMvcProperties”。我看下WebMvcProperties類的定義。@ConfigurationProperties(prefix = "spring.mvc")
public class WebMvcProperties
{
。。。省略
}
註解的prefix屬性值是"spring.mvc",這個意思就是把application.*中所有前綴是spring.mvc的配置數據綁定到WebMvcProperties的屬性,換句話說,就是WebMvcProperties持有所有關於spring mvc的配置。
@ConfigurationProperties註解本身的功能我就不介紹了,大家可以百度下,支持鬆散命名,支持jsr303校驗。比如說,WebMvcProperties中某個屬性被jsr303校驗器註解了,那麼從application.*中把配置數據綁定到屬性前,會先對配置值執行校驗。可能大家又會有個疑問,是誰負責把application.*中的配置數據輸送到對象呢,這個行爲發生在什麼時候?
三. 誰負責把application.*中的配置數據輸送到對象,何時輸送。
執行輸送任務的是ConfigurationPropertiesBindingPostProcessor(一個bean後處理器),在創建bean對象過程中的初始化bean步驟之前發生。那麼,ConfigurationPropertiesBindingPostProcessor又是被誰註冊到bean工廠的呢?答案是@EnableConfigurationProperties,我們看下這個註解的定義。
@Import(EnableConfigurationPropertiesImportSelector.class)
public @interface EnableConfigurationProperties
{
。。。省略
}
這個註解本身又被@Import(EnableConfigurationPropertiesImportSelector.class)註解了,被導入的EnableConfigurationPropertiesImportSelector是一個導入選擇器,這個類的作用是導入“ConfigurationPropertiesBeanRegistrar.class”和“ConfigurationPropertiesBindingPostProcessorRegistrar.class”,被導入的這兩個類有一個共同的特點,它們都實現了ImportBeanDefinitionRegistrar接口,也就是說被導入的這兩個類本身的作用是往bean工廠註冊bean定義對象的。
ConfigurationPropertiesBindingPostProcessorRegistrar:負責註冊ConfigurationPropertiesBindingPostProcessor,這個bean後處理器的作用前面說了。
ConfigurationPropertiesBeanRegistrar : 負責註冊配置類依賴的被@ConfigurationProperties註解的類,比如DispatcherServletConfiguration依賴WebMvcProperties,於是乎WebMvcProperties也被註冊到bean工廠了。
那麼,爲什麼會發生上述操作呢,答案是spring boot默認定義一些被@EnableConfigurationProperties註解的配置類,比如DispatcherServletConfiguration,我們看下它的定義。
@EnableConfigurationProperties(WebMvcProperties.class)
protected static class DispatcherServletConfiguration
{
。。。
}
不知道讀者看到這裏是被饒暈了,還是有種恍然大悟的感覺呢!