揭秘 @Autowired 自動(dòng)裝配原理與實(shí)現(xiàn)機(jī)制
前言
在Java開(kāi)發(fā)中,Spring框架憑借強(qiáng)大的依賴(lài)注入(Dependency Injection,DI)功能極大地提升了代碼的可維護(hù)性和可擴(kuò)展性。其中,@Autowired注解作為Spring實(shí)現(xiàn)依賴(lài)注入的核心手段之一,被開(kāi)發(fā)者廣泛使用。
但@Autowired究竟是如何實(shí)現(xiàn)自動(dòng)裝配的呢?本文將深入剖析其原理與實(shí)現(xiàn)機(jī)制,揭開(kāi)它的神秘面紗。
自動(dòng)裝配的核心流程
啟動(dòng)容器時(shí)的掃描與解析
當(dāng)Spring容器啟動(dòng)時(shí),會(huì)根據(jù)配置(如XML 配置或注解配置)掃描指定包路徑下的類(lèi)。對(duì)于被@Component、@Service、@Repository、@Controller等注解標(biāo)注的類(lèi),Spring會(huì)將其注冊(cè)為Bean,并存儲(chǔ)在容器的BeanDefinition注冊(cè)表中。在這個(gè)過(guò)程中,如果遇到帶有@Autowired注解的字段、方法或構(gòu)造函數(shù),會(huì)記錄下依賴(lài)關(guān)系信息。
實(shí)例化與依賴(lài)注入
在創(chuàng)建Bean實(shí)例時(shí),Spring會(huì)根據(jù)BeanDefinition中的信息,首先實(shí)例化Bean(對(duì)于單例Bean,只會(huì)實(shí)例化一次)。在實(shí)例化完成后,Spring會(huì)處理@Autowired注解。對(duì)于字段上的@Autowired,Spring會(huì)在容器中查找與字段類(lèi)型匹配的Bean。查找過(guò)程中,會(huì)優(yōu)先按照類(lèi)型匹配,如果存在多個(gè)同類(lèi)型的Bean,則會(huì)根據(jù)字段名或使用@Qualifier注解指定的名稱(chēng)進(jìn)一步篩選。找到匹配的Bean后,將其注入到對(duì)應(yīng)字段。
循環(huán)依賴(lài)處理
圖片
在自動(dòng)裝配過(guò)程中,可能會(huì)遇到循環(huán)依賴(lài)的情況,即兩個(gè)或多個(gè)Bean之間相互依賴(lài)。Spring容器通過(guò)三級(jí)緩存機(jī)制來(lái)處理循環(huán)依賴(lài)問(wèn)題。一級(jí)緩存存儲(chǔ)完全初始化好的Bean;二級(jí)緩存存儲(chǔ)早期暴露的Bean(尚未完成屬性填充和初始化);三級(jí)緩存存儲(chǔ)Bean 的創(chuàng)建工廠。當(dāng)檢測(cè)到循環(huán)依賴(lài)時(shí),Spring會(huì)從二級(jí)緩存中獲取早期暴露的Bean,避免因循環(huán)依賴(lài)導(dǎo)致的死循環(huán)問(wèn)題。
Bean的初始化過(guò)程
Spring的可以分為5個(gè)小的階段:實(shí)例化、初始化、注冊(cè)Destruction回調(diào)、Bean的正常使用以及Bean的銷(xiāo)毀。
圖片
- 實(shí)例化(Instantiation):
- 實(shí)例化是創(chuàng)建對(duì)象的過(guò)程。在Spring中,這通常指的是通過(guò)調(diào)用類(lèi)的構(gòu)造器來(lái)創(chuàng)建Bean的實(shí)例。這是對(duì)象生命周期的開(kāi)始階段。對(duì)應(yīng)doCreateBean中的createBeanInstance方法。
- 初始化(Initialization):
- 初始化是在Bean實(shí)例創(chuàng)建后,進(jìn)行一些設(shè)置或準(zhǔn)備工作的過(guò)程。在Spring中,包括設(shè)置Bean的屬性,調(diào)用各種前置&后置處理器。對(duì)應(yīng)doCreateBean中的populateBean和initializeBean方法。
自動(dòng)裝配其實(shí)發(fā)生在Instantiation -> Populate -> Initialization的過(guò)程中,屬于Bean的生命周期中的populate階段。
- 在實(shí)例化Bean的時(shí)候在createBeanInstance方法中會(huì)調(diào)用 AutowiredAnnotationBeanPostProcessor中的方法來(lái)獲取需要自動(dòng)注入的構(gòu)造方法,AutowiredAnnotationBeanPostProcessor的方法來(lái)完成對(duì)所有需要自動(dòng)注入的屬性和方法的解析和緩存。
- populatedBean方法中調(diào)用到AutowiredAnnotationBeanPostProcessor中的方法來(lái)完成需要自動(dòng)注入屬性的注入工作。
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
// 獲取Bean定義中的屬性值
PropertyValues pvs = mbd.getPropertyValues();
// 如果BeanWrapper為空,則無(wú)法設(shè)置屬性值
if (bw == null) {
if (!pvs.isEmpty()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
} else {
// 對(duì)于null實(shí)例,跳過(guò)設(shè)置屬性階段
return;
}
}
// 在設(shè)置屬性之前,給InstantiationAwareBeanPostProcessors機(jī)會(huì)修改Bean狀態(tài)
// 這可以用于支持字段注入等樣式
boolean continueWithPropertyPopulation = true;
// 如果Bean不是合成的,并且存在InstantiationAwareBeanPostProcessor,執(zhí)行后續(xù)處理
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
// 如果上述處理后決定不繼續(xù),則返回
if (!continueWithPropertyPopulation) {
return;
}
// 根據(jù)自動(dòng)裝配模式(按名稱(chēng)或類(lèi)型),設(shè)置相關(guān)的屬性值
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// 如果是按名稱(chēng)自動(dòng)裝配,添加相應(yīng)的屬性值
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// 如果是按類(lèi)型自動(dòng)裝配,添加相應(yīng)的屬性值
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
// 檢查是否需要進(jìn)行依賴(lài)性檢查
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
// 如果需要,則進(jìn)行依賴(lài)性檢查
if (hasInstAwareBpps || needsDepCheck) {
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
}
if (needsDepCheck) {
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
// 應(yīng)用屬性值
applyPropertyValues(beanName, mbd, bw, pvs);
}@Autowired 實(shí)現(xiàn)的關(guān)鍵源碼解析
@Autowired注解的實(shí)現(xiàn)主要涉及到AutowiredAnnotationBeanPostProcessor類(lèi),它繼承自InstantiationAwareBeanPostProcessorAdapter(后期被棄用,改實(shí)現(xiàn)SmartInstantiationAwareBeanPostProcessor),該類(lèi)實(shí)現(xiàn)了postProcessProperties方法,用于處理Bean的屬性注入。
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
try {
metadata.inject(bean, beanName, pvs);
}catch (BeanCreationException ex) {
throw ex;
}catch (Throwable ex) {
throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
}
return pvs;
}在postProcessProperties方法中,首先通過(guò)findAutowiringMetadata方法獲取與@Autowired相關(guān)的元數(shù)據(jù)(包括要注入的字段、方法等信息),然后調(diào)用metadata.inject方法進(jìn)行實(shí)際的依賴(lài)注入操作。metadata.inject方法會(huì)遍歷需要注入的元素,通過(guò)反射機(jī)制獲取對(duì)應(yīng)的Bean并完成注入。
總結(jié)
如果你在面試中遇到這個(gè)問(wèn)題,可以這樣回答:
- @Autowired是Spring提供的自動(dòng)裝配注解,它通過(guò)AutowiredAnnotationBeanPostProcessor實(shí)現(xiàn)依賴(lài)注入。
- 這個(gè)處理器在Bean初始化階段介入,掃描字段或方法的注解,找到需要注入的地方,然后根據(jù)類(lèi)型從容器中查找Bean,通過(guò)反射完成注入。
- 如果存在多個(gè)實(shí)現(xiàn),可以通過(guò)@Qualifier或@Primary來(lái)指定注入對(duì)象。構(gòu)造器注入則在實(shí)例化時(shí)完成,推薦用于強(qiáng)依賴(lài)場(chǎng)景。


























