0.前提: 項目代碼
1.項目啟動時加載SpringBoot的主配置類SpringBootxxApplication,此類在底層加載了很多springboot帶有的bean對象到容器中.具體過程解釋如下:
因為此類上配置了@SpringBootApplication注解, 這個注解是一個復合注解或者派生注解
而此注解類上又配置了自動裝配功能 @SpringBootConfiguration和@EnableAutoConfiguration
(@EnableAutoConfiguration注解借助@SpringBootApplication被間接的標記在了Spring Boot的啟動類SpringBootxxApplication上)
@EnableAutoConfiguration注解的也是一個派生注解. 其中的關鍵功能由@import 提供其導入的AutoConfigurationImportSelector的selectImports()方法通過來給spring完成自動配置(當運行SpringBoot的啟動類時,會運行 SpringApplication.run().在run運行時,這些注解就會生效,就會執行selectImports方法,selectImports方法通過SpringFactoriesLoader.loadFactoryNames()掃描項目的類庫中每個jar包,看其是否有META-INF/spring.factories文件. 此文件的內容是一個key多個value<每個value用逗號分隔>. 如果有這樣的文件就加載此文件配置的所有類, 並將它們讀取到內存, 它們大多數形成實例對象都是需要條件的,如果它們形成了實例對象就把實例對象納入到spring容器中管理)。
底下是AutoConfigurationImportSelector的selectImports()方法通過SpringFactoriesLoader.loadFactoryNames()源碼調用次序.
比如: spring-boot-autoconfigure-2.3.0.RELEASE.jar里就有一個這樣的spring.factories文件。
這個spring.factories文件也是一組一組的key=value的形式,其中一個key是EnableAutoConfiguration類的全類名,而它的value是一個xxxxAutoConfiguration的類名的列表,這些類名以逗號分隔,如下圖所示:
注意: 上邊的spring.factories文件內的value中的值每一個XxxxAutoConfiguration自動配置類都是在某些條件之下才會生效的.
這些條件在每個XxxxAutoConfiguration類上以注解的形式體現, 常見的條件注解有如下幾項:
注: 以XxxxAutoConfiguration形式在觸發條件時導入一些配置類對象被稱作JavaConfig形式.
以ServletWebServerFactoryAutoConfiguration類為例,解釋一下全局配置文件中的屬性值(比如:server.port=8081)如何生效,(當然不配置也會有默認值,這個默認值來自於org.apache.catalina.startup.Tomcat)。
本類上,有一個@EnableConfigurationProperties注解:作用是開啟配置屬性,而它后面的參數是一個ServerProperties類,這就是配置的最終落地點。(@EnableConfigurationProperties注解負責將有屬性值的ServerProperties對象導入到spring容器中)
而ServerProperties注解用@ConfigurationProperties. 它的作用是從配置文件中讀取屬性值綁定到對應的bean對象上
而@EnableConfigurationProperties負責導入這個已經綁定了屬性值的bean到spring容器中(ServerProperties類與配置文件中以prefix開頭的一組鍵值對是一一對應的)
再次精簡解釋@ConfigurationProperties和@EnableConfigurationProperties:在全局配置文件中的屬性值如:server.port等,通過@ConfigurationProperties注解,綁定到對應的XxxxProperties(例如ServerProperties)一個bean對象上,然后再通過@EnableConfigurationProperties注解將bean對象導入到Spring容器中(在容器中的ServerProperties對象內擁有屬性值, 這些數據可以供項目來使用)。
但面試的時候,其實遠遠不需要回答的這么具體,對於上邊這么長的一大段解釋只需要這樣精簡的回答:
Spring Boot啟動的時候會通過@EnableAutoConfiguration注解找到META-INF/spring.factories配置文件中的所有自動配置類,並對其進行加載,而這些自動配置類的名字都是以AutoConfiguration結尾的,它實際上就是一個JavaConfig形式的Spring容器配置類,它能通過以Properties結尾命名的類中取得在全局配置文件中配置的屬性值如:server.port,而XxxxProperties類是通過@ConfigurationProperties注解與全局配置文件中對應的屬性進行綁定的。
用圖片的形式解釋上邊精簡的總結
2.這些XxxxAutoConfiguration類的作用就是自動掃描啟動類所在包及其子包中的類,並加載到內存
3.然后檢測類上是否有Spring框架中指定的注解描述(例如@Component,@Controller,@Service 等)
4.假如有,則將類交給Spring框架中的BeanFactory工廠接口的實現類對象,此工廠對象會基於反射創建Bean的實例.
(假如此Bean指定了生命周期方法,還會調用生命周期方法<@PostConstruct, @PreDestroy等>)
5.當實例創建以后,Spring框架還會基於類的作用域描述,將實例存儲到不同作用域的容器中。以實現Bean對象的科學應用。