一、前言
Spring的出現(xiàn)給我們管理bean的依賴注入提供了便捷,但是當(dāng)我們需要使用通過pom引入的jar里面的一個bean時候,還是需要手動在xml配置文件里面主要注入的bean 。springboot則可以依據(jù)classpath里面的依賴內(nèi)容來自動配置bean到IOC容器,Auto-configuration會嘗試推斷哪些beans是用戶可能會需要的。比如如果HSQLDB包在當(dāng)前classpath下,并且用戶并沒有配置其他數(shù)據(jù)庫鏈接,這時候Auto-configuration功能會自動注入一個基于內(nèi)存的數(shù)據(jù)庫連接到應(yīng)用的IOC容器。但是要開啟這個自動配置功能需要添加@EnableAutoConfiguration注解。
Auto-configuration使用在class上標(biāo)注@Configuration注解實現(xiàn),并且使用@Configuration的時候一般帶有一定的約束,比如同時還在class上標(biāo)注了 @ConditionalOnClass(當(dāng)前classpath下存在類) 和@ConditionalOnMissingBean(當(dāng)前IOC容器不存在bean)注解。這保證了classpath下存在一些相關(guān)的類并且需要的bean還沒有被注入到IOC時候auto-configuration才生效。
二、一個例子-web容器的自動配置
本節(jié)通過web容器創(chuàng)建的過程來分析下Auto-configuration是如何實現(xiàn)自動掃描裝載的。

- EmbeddedServletContainerAutoConfiguration類是web容器的Auto-configuration類。
- @ConditionalOnWebApplication說明當(dāng)前是web環(huán)境上下文時候才注入本類到IOC。
- 對應(yīng)tomcat來說它的核心代碼里面需要Servlet.class, Tomcat.class這兩個類,所以 @ConditionalOnClass({ Servlet.class, Tomcat.class })說明如果當(dāng)前classpath的jar里面含有Servlet.class, Tomcat.class這兩個類,才進(jìn)入下一個條件的判斷, @ConditionalOnMissingBean(value = EmbeddedServletContainerFactory.class, search = SearchStrategy.CURRENT)說明當(dāng)前IOC容器里面是否沒有EmbeddedServletContainerFactory的實例,如果兩個條件都滿足則會創(chuàng)建TomcatEmbeddedServletContainerFactory實例到IOC容器。
- 對應(yīng)Jetty來說它的核心代碼里面需要Servlet.class, Server.class, Loader.class,WebAppContext.class,所以@ConditionalOnClass({ Servlet.class, Server.class, Loader.class,WebAppContext.class })是看當(dāng)前classpath的jar里面是否含有這些類,這些類存在進(jìn)入下一個條件看當(dāng)前IOC容器里面是否沒有EmbeddedServletContainerFactory的實例。
當(dāng)應(yīng)用引入spring-boot-starter-web時候默認(rèn)是引入的是tomcat的start,所以會發(fā)現(xiàn)classpath下存在Servlet.class, Tomcat.class這兩個類,并且IOC里面沒有EmbeddedServletContainerFactory的實例,所以會創(chuàng)建TomcatEmbeddedServletContainerFactory到IOC。如果你需要使用Jetty則需要在引用spring-boot-starter-web的時候排除掉tomcat的start,然后在引入jetty的start即可。
注:JettyEmbeddedServletContainerFactory和TomcatEmbeddedServletContainerFactory都實現(xiàn)了EmbeddedServletContainerFactory接口。
三、總結(jié)
springboot的spring-boot-autoconfigure模塊通過靈活的Auto-configuration注解使SpringBoot中的功能實現(xiàn)模塊化和可被替換擴(kuò)展。spring-boot-autoconfigure思路類似SPI(Service Provider Interface),都是不同的實現(xiàn)類實現(xiàn)了定義的接口,加載時候去查找classpath下的實現(xiàn)類,不同在于前者使用autoconfigure實現(xiàn)后者使用的是ServiceLoader。