Spring內(nèi)核探秘:從BeanDefinition到完整Bean的涅槃之旅

本文不滿足于表面使用,將直擊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í)例化的策略,SimpleInstantiationStrategyCglibSubclassingInstantiationStrategy是不同的實(shí)現(xiàn)。

7.4 觀察者模式

Spring的事件機(jī)制ApplicationEventApplicationListener是觀察者模式的典型應(yīng)用。

總結(jié)

通過深度剖析Spring IoC容器的源碼,我們可以得出以下核心理解:

  1. BeanDefinition是基石:所有的Bean創(chuàng)建都基于BeanDefinition的元數(shù)據(jù)。
  2. refresh()是生命線:理解這個(gè)方法就理解了Spring容器的完整生命周期。
  3. BeanPostProcessor是擴(kuò)展點(diǎn):Spring的AOP、事務(wù)、異步等特性都通過BeanPostProcessor實(shí)現(xiàn)。
  4. 三級(jí)緩存解決循環(huán)依賴:這是Spring框架設(shè)計(jì)精妙的集中體現(xiàn)。
  5. 接口驅(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框架的精髓!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容