在SpringBoot啟動類中,該主類被@SpringBootApplication所修飾,跟蹤該註解類,除元註解外,該註解類被如下自定註解修飾。
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan
讓我們簡單敘述下它們各自的功能:
我們來看下@SpringBootConfiguration
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
@AliasFor(
annotation = Configuration.class
)
boolean proxyBeanMethods() default true;
}
可以看到該註解類內包含與@Configuration,其作用與@Configuration並無太大區別,只是多了層屬性巢狀。
故: @SpringBootConfiguration + @ComponentScan
將根目錄下所有被**@Controller、@Service、@Repository、@Component**等所修飾的類交給IoC容器管理。
那麼重點來了,@EnableAutoConfiguration是如何裝載第三方Bean的呢?讓我們跟蹤下它的原始碼。
首先我們可以看到該類被如下註解修飾:
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
我們先關注下AutoConfigurationImportSelector這個元件。
// 批次匯入第三方的一些Bean
@Import({AutoConfigurationImportSelector.class})
其中該元件的selectImports(AnnotationMetadata annotationMetadata)方法,掃描所有需要被管理的第三方Bean並交給IoC容器進行管理。
那麼SpringBoot又是如何取感知第三方的Bean檔案呢?
SpringBoot和第三方Bean之間存在一定的規定。即通過對於相應依賴的Jar包中可能存在一個spring.factories檔案,在該檔案中就記錄了需要被IoC容器管理的Bean檔案路徑,SpringBoot通過該檔案確定需要IoC管理的Bean檔案位置。對於spring-boot-autoconfiguration的spring.factories檔案中,記錄著大量xxxAutoConfiguration的類檔案位置,這些類都被@Configuration註解標識,即這些設定類會設定多個Bean從而解決spring.factories可能產生的臃腫問題。
Tomcat的載入時機
對於SpringBoot來說它特點不僅是簡化設定,還有內嵌容器等特點。那麼就有必要探討Tomcat容器的載入時機。在spring-boot-autoconfiguration的spring.factories檔案中存在ServletWebServerFactoryAutoConfiguration設定類的路徑,該類會在專案啟動時將預設的Tomcat容器已@Bean的方式載入入IoC容器內部。
SpringBoot是如何集中設定呢?
談論這個問題前我們不妨先按照之前yml或properties的檔案設定下
server:
port: 8080
通過IDE,跟蹤到port所設定的成員變數所在類,發現該類被@ConfigurationProperties所修飾,該註解就是將yml或properties中設定按照對應字首注入到指定類的成員變數。該註解具體實現感興趣的小夥伴們可以去如下連結學習。@ConfigurationProperties實現原理與實戰
@ConfigurationProperties(prefix = "server", ignoreUnknownFields = true)
public class ServerProperties {
private Integer port;
*******
}
下面兩個程式碼和前述作用大致相同
environment.getProperty("xxx");
@Value("${xxx}")
已經知道了SpringBoot如何簡化設定,那麼我們也可以自己來實現一個starter交給SpringBoot來使用,只要在對應Jar包中新增spring.factories檔案,在其中新增如下程式碼。
org.springframework.boot.autoconfigure.EnableAutoConfiguration=xxxAutoConfiguration
大家若有時間還請實現下自己的starter依賴,對加深這部分理解還是很有幫助的。
最後我們在說下最後@SpringBootApplication中@AutoConfigurationPackage這個註解類,發現其中匯入了Registrar元件。
@Import({Registrar.class})
讓我們重點關注registerBeanDefinitions這個方法,該方法最終會來到DefaultListableBeanFactory中registerBeanDefinition(String beanName, BeanDefinition beanDefinition)方法,將AutoConfigurationPackages.Registrar.class匯入到IoC容器中,然後將主設定類所在包下所有元件匯入到SpringIoC容器中
怎麼樣,在為我們簡化了設定的同時,SpringBoot居然幫我們做了如此多的事情,而我們只需要簡單地集中設定其中一部分的屬性。關於SpirngBoot我們就探討到這裡,這些內容是閱讀一些文章,觀看部分講解和原始碼的總結,若有錯誤還請接納與指教。最後感謝各位的閱讀。