本文不滿足于表面使用,將直擊Spring框架的核心——IoC容器,通過源碼逐層剖析,揭示其背后的設(shè)計(jì)精妙與實(shí)現(xiàn)原理。
一、Spring IoC容器總體架構(gòu):設(shè)計(jì)藍(lán)圖
在深入代碼之前,必須先理解Spring IoC容器的頂層設(shè)計(jì)。整個(gè)容器體系圍繞BeanFactory這一核心接口構(gòu)建,其核心繼承體系如下:
// 核心接口繼承鏈
BeanFactory → ListableBeanFactory → ConfigurableBeanFactory
→ HierarchicalBeanFactory → ApplicationContext
1.1 核心接口職責(zé)分離
public interface BeanFactory {
// 1. 基礎(chǔ)Bean獲取能力
Object getBean(String name) throws BeansException;
<T> T getBean(String name, Class<T> requiredType) throws BeansException;
// 2. 類型檢查與作用域判斷
boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
}
public interface ListableBeanFactory extends BeanFactory {
// 3. 批量Bean查詢能力
String[] getBeanDefinitionNames();
<T> Map<String, T> getBeansOfType(Class<T> type) throws BeansException;
}
public interface ConfigurableBeanFactory extends HierarchicalBeanFactory, SingletonBeanRegistry {
// 4. 容器配置能力
void addBeanPostProcessor(BeanPostProcessor beanPostProcessor);
void registerScope(String scopeName, Scope scope);
void destroySingletons();
}
設(shè)計(jì)哲學(xué):通過精細(xì)的接口拆分,實(shí)現(xiàn)了"單一職責(zé)原則",每個(gè)接口只關(guān)注特定方面的功能,使得整個(gè)架構(gòu)高度可擴(kuò)展。
二、BeanDefinition:Bean的"藍(lán)圖"
在Spring中,Bean并不是直接創(chuàng)建的,而是先通過BeanDefinition來描述Bean的元數(shù)據(jù)。
2.1 BeanDefinition核心結(jié)構(gòu)
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
// 作用域常量
String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;
String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;
// Bean類信息
void setBeanClassName(String beanClassName);
String getBeanClassName();
// 作用域控制
void setScope(String scope);
String getScope();
// 生命周期配置
void setLazyInit(boolean lazyInit);
boolean isLazyInit();
void setInitMethodName(String initMethodName);
String getInitMethodName();
// 依賴關(guān)系
void setDependsOn(String... dependsOn);
String[] getDependsOn();
// 是否是主要候選者(@Primary)
void setPrimary(boolean primary);
boolean isPrimary();
}
2.2 BeanDefinition的注冊(cè)過程
讓我們跟蹤ClassPathXmlApplicationContext的啟動(dòng)過程:
public class ClassPathXmlApplicationContext extends AbstractXmlApplicationContext {
public ClassPathXmlApplicationContext(String[] configLocations) {
// 核心啟動(dòng)流程
this(configLocations, true, null);
}
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh,
ApplicationContext parent) {
super(parent);
setConfigLocations(configLocations);
if (refresh) {
// 這是整個(gè)Spring容器啟動(dòng)的核心入口!
refresh();
}
}
}
三、refresh()方法:容器啟動(dòng)的生命線
AbstractApplicationContext.refresh()是Spring容器啟動(dòng)的核心流程,理解它就理解了Spring的整個(gè)生命周期。
3.1 refresh()方法完整流程
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 1. 準(zhǔn)備刷新上下文
prepareRefresh();
// 2. 初始化BeanFactory并加載BeanDefinitions(關(guān)鍵步驟?。? ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 3. 配置BeanFactory(設(shè)置類加載器、SPEL解析器等)
prepareBeanFactory(beanFactory);
try {
// 4. 后處理BeanFactory(留給子類擴(kuò)展)
postProcessBeanFactory(beanFactory);
// 5. 調(diào)用BeanFactoryPostProcessors(關(guān)鍵擴(kuò)展點(diǎn)?。? invokeBeanFactoryPostProcessors(beanFactory);
// 6. 注冊(cè)BeanPostProcessors(Bean后處理器)
registerBeanPostProcessors(beanFactory);
// 7. 初始化消息源(國際化)
initMessageSource();
// 8. 初始化應(yīng)用事件廣播器
initApplicationEventMulticaster();
// 9. 留給子類擴(kuò)展的onRefresh方法
onRefresh();
// 10. 注冊(cè)監(jiān)聽器
registerListeners();
// 11. 完成BeanFactory初始化,實(shí)例化所有非懶加載單例(關(guān)鍵步驟?。? finishBeanFactoryInitialization(beanFactory);
// 12. 完成刷新,發(fā)布相應(yīng)事件
finishRefresh();
} catch (BeansException ex) {
// 13. 銷毀已創(chuàng)建的Bean
destroyBeans();
// 14. 重置激活標(biāo)志
cancelRefresh(ex);
throw ex;
} finally {
// 15. 重置Spring核心中的公共內(nèi)省緩存
resetCommonCaches();
}
}
}
3.2 關(guān)鍵步驟深度解析:BeanDefinition加載
讓我們深入第2步obtainFreshBeanFactory():
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
// 1. 刷新BeanFactory
refreshBeanFactory();
// 2. 返回刷新后的BeanFactory
return getBeanFactory();
}
// 在AbstractRefreshableApplicationContext中的實(shí)現(xiàn)
@Override
protected final void refreshBeanFactory() throws BeansException {
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
// 創(chuàng)建新的BeanFactory(默認(rèn)是DefaultListableBeanFactory)
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
// 定制BeanFactory(設(shè)置是否允許覆蓋、循環(huán)依賴等)
customizeBeanFactory(beanFactory);
// 加載BeanDefinitions(這是模板方法,由子類實(shí)現(xiàn))
loadBeanDefinitions(beanFactory);
this.beanFactory = beanFactory;
} catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source", ex);
}
}
四、Bean創(chuàng)建過程:從定義到實(shí)例的涅槃
第11步finishBeanFactoryInitialization(beanFactory)是Bean實(shí)例化的核心:
4.1 Bean創(chuàng)建時(shí)序圖
getBean() → doGetBean() → createBean() → doCreateBean()
↓
resolveBeanClass() → instantiateBean() → populateBean() → initializeBean()
4.2 核心源碼解析
// AbstractBeanFactory
protected <T> T doGetBean(String name, Class<T> requiredType,
Object[] args, boolean typeCheckOnly) {
// 1. 轉(zhuǎn)換Bean名稱(處理FactoryBean、別名等)
String beanName = transformedBeanName(name);
// 2. 嘗試從緩存中獲取單例
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
return getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
// 3. 檢查BeanDefinition是否存在
BeanDefinition bd = getMergedBeanDefinition(beanName);
// 4. 處理依賴的Bean(depends-on)
String[] dependsOn = bd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
// 遞歸初始化依賴的Bean
getBean(dep);
registerDependentBean(dep, beanName);
}
}
// 5. 根據(jù)作用域創(chuàng)建Bean實(shí)例
if (bd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, bd, args);
} catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
});
return getObjectForBeanInstance(sharedInstance, name, beanName, bd);
} else if (bd.isPrototype()) {
// 原型模式每次都創(chuàng)建新實(shí)例
Object prototypeInstance = createBean(beanName, bd, args);
return getObjectForBeanInstance(prototypeInstance, name, beanName, bd);
} else {
// 其他作用域(request、session等)
String scopeName = bd.getScope();
Scope scope = this.scopes.get(scopeName);
Object scopedInstance = scope.get(beanName, () -> {
return createBean(beanName, bd, args);
});
return getObjectForBeanInstance(scopedInstance, name, beanName, bd);
}
}
4.3 createBean的真正實(shí)現(xiàn)
// AbstractAutowireCapableBeanFactory
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) {
// 1. 解析Bean類
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
// 2. 準(zhǔn)備方法覆蓋(lookup-method, replace-method)
mbdToUse.prepareMethodOverrides();
// 3. 給BeanPostProcessors機(jī)會(huì)返回代理而不是目標(biāo)Bean(AOP的關(guān)鍵?。? Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
// 4. 真正的創(chuàng)建Bean實(shí)例
return doCreateBean(beanName, mbdToUse, args);
}
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, Object[] args) {
BeanWrapper instanceWrapper = null;
// 4.1 實(shí)例化Bean(調(diào)用構(gòu)造方法)
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// 4.2 應(yīng)用MergedBeanDefinitionPostProcessors(@Autowired注解在這里處理)
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
// 4.3 屬性填充(依賴注入!)
populateBean(beanName, mbd, instanceWrapper);
// 4.4 初始化Bean
Object exposedObject = initializeBean(beanName, exposedObject, mbd);
return exposedObject;
}
五、依賴注入:@Autowired的實(shí)現(xiàn)原理
讓我們深入populateBean方法,看看Spring是如何實(shí)現(xiàn)依賴注入的:
5.1 自動(dòng)裝配的核心邏輯
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
// 1. 如果有屬性值,先設(shè)置屬性值
PropertyValues pvs = mbd.getPropertyValues();
// 2. 調(diào)用InstantiationAwareBeanPostProcessors(在設(shè)置屬性之前)
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
}
// 3. 自動(dòng)裝配ByName和ByType
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME ||
mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// 根據(jù)名稱自動(dòng)裝配
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// 根據(jù)類型自動(dòng)裝配
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
// 4. 調(diào)用InstantiationAwareBeanPostProcessors的postProcessProperties方法
// 這里就是@Autowired注解處理的地方!
if (hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
// 兼容老版本
pvsToUse = ibp.postProcessPropertyValues(pvs,
filteredPds, bw.getWrappedInstance(), beanName);
}
if (pvsToUse != null) {
pvs = pvsToUse;
}
}
}
}
// 5. 應(yīng)用屬性值
applyPropertyValues(beanName, mbd, bw, pvs);
}
5.2 @Autowired注解處理器
AutowiredAnnotationBeanPostProcessor是處理@Autowired注解的核心類:
public class AutowiredAnnotationBeanPostProcessor implements
InstantiationAwareBeanPostProcessor, MergedBeanDefinitionPostProcessor {
// 1. 后處理合并的BeanDefinition,查找所有需要自動(dòng)裝配的元數(shù)據(jù)
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition,
Class<?> beanType, String beanName) {
// 查找被@Autowired注解的字段和方法
InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
metadata.checkConfigMembers(beanDefinition);
}
// 2. 屬性填充階段進(jìn)行依賴注入
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
// 獲取注入元數(shù)據(jù)
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
try {
// 進(jìn)行注入!
metadata.inject(bean, beanName, pvs);
} catch (Throwable ex) {
throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
}
return pvs;
}
// 3. 構(gòu)建注入元數(shù)據(jù)
private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz,
PropertyValues pvs) {
String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
return this.injectionMetadataCache.computeIfAbsent(cacheKey, k -> {
// 反射查找被@Autowired注解的字段和方法
List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
Class<?> targetClass = clazz;
do {
List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();
// 處理字段
ReflectionUtils.doWithLocalFields(targetClass, field -> {
AnnotationAttributes ann = findAutowiredAnnotation(field);
if (ann != null) {
if (Modifier.isStatic(field.getModifiers())) {
return; // 靜態(tài)字段不注入
}
boolean required = determineRequiredStatus(ann);
currElements.add(new AutowiredFieldElement(field, required));
}
});
// 處理方法
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
AnnotationAttributes ann = findAutowiredAnnotation(bridgedMethod);
if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
if (Modifier.isStatic(method.getModifiers())) {
return; // 靜態(tài)方法不注入
}
if (method.getParameterCount() == 0) {
return; // 無參數(shù)方法不處理
}
boolean required = determineRequiredStatus(ann);
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
currElements.add(new AutowiredMethodElement(method, required, pd));
}
});
elements.addAll(0, currElements);
targetClass = targetClass.getSuperclass();
} while (targetClass != null && targetClass != Object.class);
return new InjectionMetadata(clazz, elements);
});
}
}
六、循環(huán)依賴:Spring的三級(jí)緩存解決方案
Spring通過三級(jí)緩存巧妙地解決了單例Bean的循環(huán)依賴問題:
6.1 三級(jí)緩存定義
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
// 一級(jí)緩存:存放完全初始化好的Bean
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
// 二級(jí)緩存:存放早期暴露的Bean(已實(shí)例化但未填充屬性)
private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);
// 三級(jí)緩存:存放Bean工廠,用于生成早期引用
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
// 正在創(chuàng)建中的Bean
private final Set<String> singletonsCurrentlyInCreation =
Collections.newSetFromMap(new ConcurrentHashMap<>(16));
}
6.2 循環(huán)依賴解決流程
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 1. 從一級(jí)緩存查找
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
// 2. 從二級(jí)緩存查找
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
// 3. 從三級(jí)緩存獲取ObjectFactory
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
// 4. 調(diào)用getObject方法獲取早期引用(可能經(jīng)過AOP代理)
singletonObject = singletonFactory.getObject();
// 5. 放入二級(jí)緩存,清除三級(jí)緩存
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
七、設(shè)計(jì)模式在Spring源碼中的應(yīng)用
Spring源碼是設(shè)計(jì)模式應(yīng)用的典范:
7.1 模板方法模式
AbstractApplicationContext.refresh()方法定義了容器啟動(dòng)的整體流程,具體步驟由子類實(shí)現(xiàn)。
7.2 工廠模式
BeanFactory是典型的工廠模式,隱藏了Bean創(chuàng)建的復(fù)雜細(xì)節(jié)。
7.3 策略模式
InstantiationStrategy定義了Bean實(shí)例化的策略,SimpleInstantiationStrategy和CglibSubclassingInstantiationStrategy是不同的實(shí)現(xiàn)。
7.4 觀察者模式
Spring的事件機(jī)制ApplicationEvent和ApplicationListener是觀察者模式的典型應(yīng)用。
總結(jié)
通過深度剖析Spring IoC容器的源碼,我們可以得出以下核心理解:
- BeanDefinition是基石:所有的Bean創(chuàng)建都基于BeanDefinition的元數(shù)據(jù)。
- refresh()是生命線:理解這個(gè)方法就理解了Spring容器的完整生命周期。
- BeanPostProcessor是擴(kuò)展點(diǎn):Spring的AOP、事務(wù)、異步等特性都通過BeanPostProcessor實(shí)現(xiàn)。
- 三級(jí)緩存解決循環(huán)依賴:這是Spring框架設(shè)計(jì)精妙的集中體現(xiàn)。
- 接口驅(qū)動(dòng)設(shè)計(jì):精細(xì)的接口劃分使得Spring框架高度可擴(kuò)展。
理解Spring源碼不僅能夠幫助我們更好地使用Spring,更重要的是能夠?qū)W習(xí)到優(yōu)秀框架的設(shè)計(jì)思想和架構(gòu)模式,這對(duì)于提升我們的系統(tǒng)設(shè)計(jì)能力有著不可估量的價(jià)值。
希望這篇深度源碼解析能夠幫助您真正理解Spring框架的精髓!