SpringBoot的自動(dòng)裝配,你學(xué)會(huì)了嗎?
我們今天再來(lái)說(shuō)一下關(guān)于 SpringBoot 的自動(dòng)裝配,為什么會(huì)有這樣的問(wèn)題呢?一般這種情況都是在面試的過(guò)程中,面試官有時(shí)候會(huì)問(wèn)到這個(gè)問(wèn)題,就比如從開(kāi)始問(wèn)SpringBoot 的一些常用注解,到SpringBoot的一些特性,然后引申到這個(gè) SpringBoot 的自動(dòng)裝配上來(lái)。今天就和了不起一起來(lái)聊聊關(guān)于這個(gè) SpringBoot 的自動(dòng)裝配吧。
什么是SpringBoot的裝配
Spring Boot 的自動(dòng)裝配(Auto-Configuration)是指 Spring Boot 會(huì)根據(jù)項(xiàng)目中添加的依賴(lài)和其他因素,自動(dòng)配置你的 Spring 應(yīng)用程序。這一特性使得開(kāi)發(fā)者在創(chuàng)建 Spring 應(yīng)用程序時(shí),可以省去大量的手動(dòng)配置工作,從而快速啟動(dòng)和運(yùn)行應(yīng)用程序。
自動(dòng)裝配流程
SpringBoot的自動(dòng)裝配工作流程主要基于其核心注解和一系列的配置機(jī)制,以下是對(duì)其工作流程的詳細(xì)解析:
1.啟動(dòng)注解:
- SpringBoot的自動(dòng)裝配始于@SpringBootApplication注解。這個(gè)注解實(shí)際上是@SpringBootConfiguration、@EnableAutoConfiguration和@ComponentScan三個(gè)注解的組合。
2.@SpringBootConfiguration:
- @SpringBootConfiguration注解本質(zhì)上是一個(gè)@Configuration注解的包裝,用于聲明當(dāng)前類(lèi)是一個(gè)配置類(lèi),可以定義Bean,也可以引入其他配置類(lèi)。
3.@EnableAutoConfiguration:
- 這是實(shí)現(xiàn)自動(dòng)裝配的關(guān)鍵注解。它包含了@AutoConfigurationPackage和@Import(AutoConfigurationImportSelector.class)兩個(gè)子注解。
- @AutoConfigurationPackage:用于自動(dòng)配置包,使得主配置類(lèi)(帶有@SpringBootApplication注解的類(lèi))所在的包及其子包中的組件都能被Spring容器掃描到。
- @Import(AutoConfigurationImportSelector.class):這個(gè)注解的作用是導(dǎo)入類(lèi),但在這里它并不是直接導(dǎo)入一個(gè)普通的類(lèi),而是導(dǎo)入了一個(gè)實(shí)現(xiàn)了ImportSelector接口的類(lèi)AutoConfigurationImportSelector。這個(gè)類(lèi)的作用是根據(jù)一定的規(guī)則(比如類(lèi)路徑下的META-INF/spring.factories文件)來(lái)加載并配置一些自動(dòng)裝配的類(lèi)。
4.META-INF/spring.factories:
- 在Spring Boot的自動(dòng)裝配過(guò)程中,META-INF/spring.factories文件起到了非常關(guān)鍵的作用。這個(gè)文件是Spring Boot用來(lái)加載自動(dòng)配置類(lèi)的一個(gè)約定俗成的文件,它位于各個(gè)Spring Boot Starter的jar包中。Spring Boot在啟動(dòng)時(shí),會(huì)掃描所有jar包中的META-INF/spring.factories文件,并將其中配置的自動(dòng)配置類(lèi)加載到Spring容器中。
5.自動(dòng)配置類(lèi):
- 這些類(lèi)通常是以AutoConfiguration結(jié)尾的,它們使用@Configuration注解標(biāo)注,并且內(nèi)部定義了一些Bean。這些Bean就是Spring Boot自動(dòng)裝配到Spring容器中的組件。
6.條件裝配:
- 在自動(dòng)配置類(lèi)中,經(jīng)??梢钥吹紷ConditionalOnClass、@ConditionalOnProperty等條件注解。這些注解的作用是判斷當(dāng)前環(huán)境是否滿(mǎn)足某個(gè)條件,如果滿(mǎn)足則進(jìn)行自動(dòng)裝配,否則不進(jìn)行裝配。這樣可以根據(jù)項(xiàng)目的實(shí)際情況來(lái)靈活地選擇需要裝配的組件。
7.總結(jié):
SpringBoot的自動(dòng)裝配工作流程大致可以歸納為:首先通過(guò)@SpringBootApplication注解啟動(dòng)Spring Boot應(yīng)用,然后利用@EnableAutoConfiguration注解中的@Import(AutoConfigurationImportSelector.class)來(lái)加載META-INF/spring.factories文件中配置的自動(dòng)配置類(lèi),最后根據(jù)這些自動(dòng)配置類(lèi)中的定義和條件注解來(lái)將相應(yīng)的組件裝配到Spring容器中。
自動(dòng)裝配的核心
@SpringBootApplication
這個(gè)注解,就是自動(dòng)裝配的核心,我們來(lái)詳細(xì)解讀一下這個(gè) @SpringBootApplication
它其實(shí)是一個(gè)組合注解,用于簡(jiǎn)化 Spring Boot 應(yīng)用的配置。這個(gè)注解通常被用在 Spring Boot 的主類(lèi)上,以指示該類(lèi)是一個(gè)特殊的配置類(lèi),用于引導(dǎo)應(yīng)用上下文的啟動(dòng)。
組成部分
1.@SpringBootConfiguration:
- 這是一個(gè)特殊的 @Configuration 注解,表示該類(lèi)是一個(gè)配置類(lèi),并告訴 Spring Boot 這是一個(gè)特殊的配置類(lèi),用于加載應(yīng)用的上下文設(shè)置。
- 實(shí)際上,@SpringBootConfiguration 僅僅是 @Configuration 的一個(gè)特殊版本,并且二者在功能上沒(méi)有區(qū)別。但 @SpringBootConfiguration 更多地用于標(biāo)識(shí)這是一個(gè) Spring Boot 應(yīng)用。
2.@EnableAutoConfiguration:
- 這是 Spring Boot 的核心特性之一。它告訴 Spring Boot 根據(jù)添加的 jar 依賴(lài)項(xiàng)、類(lèi)路徑設(shè)置、各種屬性設(shè)置等自動(dòng)配置你的 Spring 應(yīng)用。例如,如果你的類(lèi)路徑下有 spring-boot-starter-web,那么 Spring Boot 會(huì)自動(dòng)配置嵌入式 Tomcat 服務(wù)器和 Spring MVC。
- 你可以通過(guò) spring.autoconfigure.exclude 屬性來(lái)排除某些自動(dòng)配置。
3.@ComponentScan:
- @ComponentScan 告訴 Spring 掃描當(dāng)前包及其子包下的組件(如 @Component、@Service、@Repository、@Controller 等),并將它們注冊(cè)為 Spring Bean。
- 默認(rèn)情況下,它會(huì)掃描標(biāo)注了 @SpringBootApplication 注解的類(lèi)所在的包及其子包。你可以通過(guò) basePackages 或 basePackageClasses 屬性來(lái)指定掃描的包。
如果這個(gè)時(shí)候,我們給面試官解釋了這個(gè) SpringBoot的自動(dòng)裝配的原理之后,面試官很大程度上就開(kāi)始要往下延伸內(nèi)容了,既然 @Autowired 能實(shí)現(xiàn)了則個(gè)自動(dòng)裝配,那么還有其他注解么?以及他和 @Autowired 的區(qū)別在哪呢?
@Resource和@Autowire
@Resource 和 @Autowired 都是 Spring 框架中用于自動(dòng)裝配 bean 的注解,但它們之間有一些區(qū)別。以下是這兩個(gè)注解的主要區(qū)別:
來(lái)源不同
@Autowired 是 Spring 特有的注解,用于自動(dòng)裝配 bean。
@Resource 是 Java 的標(biāo)準(zhǔn)注解,屬于 JSR-250 規(guī)范的一部分,但 Spring 也支持它作為自動(dòng)裝配的注解。
@Autowired
@Autowired 是 Spring 特有的注解,用于自動(dòng)裝配 bean。Spring 容器會(huì)檢查 bean 的屬性、方法以及構(gòu)造器,然后使用與指定類(lèi)型相匹配的 bean 進(jìn)行自動(dòng)裝配。
- 類(lèi)型匹配:默認(rèn)情況下,@Autowired 是基于類(lèi)型(Type)的自動(dòng)裝配。如果存在多個(gè)相同類(lèi)型的 bean,那么就需要使用其他機(jī)制(如 @Qualifier 注解或 @Primary 注解)來(lái)進(jìn)一步指定。
- 構(gòu)造器注入:Spring 4.3 之后,推薦使用構(gòu)造器注入來(lái)替代字段注入,因?yàn)樗梢蕴峁└玫牟豢勺冃院蜏y(cè)試性。
- 可配置性:@Autowired 是可選的,并且可以通過(guò) Spring 的配置文件(如 XML 文件)進(jìn)行更詳細(xì)的配置。
@Resource
@Resource 是 Java EE 的一部分(來(lái)自 JSR-250),同時(shí)也是 Spring 支持的注解。它提供了更豐富的功能,包括指定名稱(chēng)(name)和類(lèi)型(type)來(lái)查找 bean。
- 名稱(chēng)和類(lèi)型匹配:與 @Autowired 相比,@Resource 提供了更靈活的匹配方式。它可以基于名稱(chēng)(如果提供了)或類(lèi)型進(jìn)行查找。如果同時(shí)指定了名稱(chēng)和類(lèi)型,并且找不到匹配的 bean,那么就會(huì)拋出異常。
- 與 Java EE 兼容:由于 @Resource 是 Java EE 的一部分,因此它可以在任何支持 Java EE 的環(huán)境中使用,而不僅僅是 Spring。
到這里,本篇文章就接近尾聲了,關(guān)于 SpringBoot的自動(dòng)裝配,你掌握了多少呢?