Spring IOC源碼解析(11)Bean加載過程

前言

前面我們分析了spring ioc邊緣化的很多組件,這些組件是分析Bean加載過程的基石?;衫斫獬上旅娴囊馑迹?/p>

  1. 基石是高層的基礎
  2. 基石可以有很多種,這些基石相互組合、繼承、擴展,從而延伸出更多高級的功能
  3. 單獨的基石只能完成某一部分相對獨立的功能,它不是完整的
  4. 基石很重要,但是基石的堆砌更重要(即:架構設計的思維)

Spring IOC最核心的功能在于Bean加載過程,也是最能體現(xiàn)架構設計高度的一塊內容。網(wǎng)上有很多這方面的分析文章,在借鑒了這些前輩經(jīng)驗的基礎上,樓主還是想將源碼閱讀的過程記錄下來,并最終對其進行分析總結。

開篇,一個最簡單的入門級例子

Spring IOC容器管理的兩個類。

public interface MessageService {
    String getMessage();
}

public class MessageServiceImpl implements MessageService {
    public String getMessage() {
        return "hello world";
    }
}

xml配置信息。

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns="http://www.springframework.org/schema/beans"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"
       default-autowire="byName">

    <bean id="messageService" class="com.juconcurrent.learn.spring.MessageServiceImpl"/>
</beans>

如何使用?

public class Main {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("classpath:application.xml");
        MessageService messageService = context.getBean(MessageService.class);
        System.out.println(messageService.getMessage());
    }
}

輸出結果:

hello world

從上面的例子我們看到,Spring IOC有兩個口子供我們分析:

  1. ClassPathXmlApplicationContext()構造方法
  2. context.getBean()方法

構造器

先來看看構造方法,其主要做了以下事情:

  1. 配置的位置可轉換成多個(即:數(shù)組),默認為一個
  2. refresh參數(shù)表示是否自動刷新上下文,默認刷新
  3. parent表示父context,默認沒有
/**
 * Create a new ClassPathXmlApplicationContext, loading the definitions
 * from the given XML file and automatically refreshing the context.
 * @param configLocation resource location
 * @throws BeansException if context creation failed
 */
public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
    this(new String[] {configLocation}, true, null);
}

/**
 * Create a new ClassPathXmlApplicationContext with the given parent,
 * loading the definitions from the given XML files.
 * @param configLocations array of resource locations
 * @param refresh whether to automatically refresh the context,
 * loading all bean definitions and creating all singletons.
 * Alternatively, call refresh manually after further configuring the context.
 * @param parent the parent context
 * @throws BeansException if context creation failed
 * @see #refresh()
 */
public ClassPathXmlApplicationContext(
        String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
        throws BeansException {

    super(parent);
    setConfigLocations(configLocations);
    if (refresh) {
        refresh();
    }
}

我們一直點super(parent),看到最內部的實現(xiàn)如下:

public abstract class AbstractApplicationContext {
    public AbstractApplicationContext(@Nullable ApplicationContext parent) {
        // 設置解析資源文件的策略類對象,可解析多種類型的資源文件,
        // 默認實現(xiàn)為`PathMatchingResourcePatternResolver`。
        this();
        // 設置父容器,在父容器不為空的情況下,父容器的`Environment`即被繼承過來。
        setParent(parent);
    }
    
    public AbstractApplicationContext() {
        this.resourcePatternResolver = getResourcePatternResolver();
    }
    
    protected ResourcePatternResolver getResourcePatternResolver() {
        return new PathMatchingResourcePatternResolver(this);
    }
    
    public void setParent(@Nullable ApplicationContext parent) {
        this.parent = parent;
        if (parent != null) {
            Environment parentEnvironment = parent.getEnvironment();
            if (parentEnvironment instanceof ConfigurableEnvironment) {
                getEnvironment().merge((ConfigurableEnvironment) parentEnvironment);
            }
        }
    }
}

接下來看看setConfigLocations()。

/**
 * 設置配置的位置。如果不設置,就是空的。
 * Set the config locations for this application context.
 * <p>If not set, the implementation may use a default as appropriate.
 */
public void setConfigLocations(@Nullable String... locations) {
    if (locations != null) {
        Assert.noNullElements(locations, "Config locations must not be null");
        this.configLocations = new String[locations.length];
        for (int i = 0; i < locations.length; i++) {
            // 這兒會使用`Environment`進行路徑解析,
            // 默認的實現(xiàn)為`StandardEnvironment`。
            this.configLocations[i] = resolvePath(locations[i]).trim();
        }
    }
    else {
        this.configLocations = null;
    }
}

protected String resolvePath(String path) {
    return getEnvironment().resolveRequiredPlaceholders(path);
}

public ConfigurableEnvironment getEnvironment() {
    if (this.environment == null) {
        this.environment = createEnvironment();
    }
    return this.environment;
}

protected ConfigurableEnvironment createEnvironment() {
    return new StandardEnvironment();
}

refresh方法

核心的代碼在于refresh()方法。之所以命名成refresh,而不是init之類的方法,有以下幾個原因:

  1. 該方法方法可反復調用
  2. 在配置變動之后,可通過該方法進行重新加載(也就是熱加載)
  3. refresh英文名為刷新,正符合當前的語境

接下來,我們分析一下這個方法。

public void refresh() throws BeansException, IllegalStateException {
    // 先來一個鎖,避免并發(fā)刷新的問題
    synchronized (this.startupShutdownMonitor) {
        // 為刷新而準備上下文
        // Prepare this context for refreshing.
        prepareRefresh();

        // 告訴子類刷新內部的bean工廠,主要做了以下幾件事:
        // 1. 如果存在bean工廠,則先銷毀其管理的所有bean,并關閉工廠
        // 2. 創(chuàng)建新的bean工廠
        // 3. 加載BeanDefinitions
        // Tell the subclass to refresh the internal bean factory.
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

        // 準備在上下文中使用這個bean工廠
        // Prepare the bean factory for use in this context.
        prepareBeanFactory(beanFactory);

        try {
            // 允許子類重寫此方法,以便增加bean工廠創(chuàng)建后的邏輯。默認什么都不做。
            // Allows post-processing of the bean factory in context subclasses.
            postProcessBeanFactory(beanFactory);

            // 調用bean工廠的后置處理器,這些處理器前面已經(jīng)注冊到了上下文
            // Invoke factory processors registered as beans in the context.
            invokeBeanFactoryPostProcessors(beanFactory);

            // 注冊bean后置處理器,在bean的創(chuàng)建過程中會被調用
            // Register bean processors that intercept bean creation.
            registerBeanPostProcessors(beanFactory);

            // 初始化消息源
            // Initialize message source for this context.
            initMessageSource();

            // 初始化上下文中的事件廣播器
            // Initialize event multicaster for this context.
            initApplicationEventMulticaster();

            // 初始化其他的特殊Bean
            // Initialize other special beans in specific context subclasses.
            onRefresh();

            // 檢查并注冊監(jiān)聽器bean
            // Check for listener beans and register them.
            registerListeners();

            // 實例化所有剩下的`non-lazy-init`單例
            // Instantiate all remaining (non-lazy-init) singletons.
            finishBeanFactoryInitialization(beanFactory);

            // 完成刷新,發(fā)布相應的事件
            // Last step: publish corresponding event.
            finishRefresh();
        }

        catch (BeansException ex) {
            if (logger.isWarnEnabled()) {
                logger.warn("Exception encountered during context initialization - " +
                        "cancelling refresh attempt: " + ex);
            }

            // 在加載過程中出現(xiàn)異常的話,將銷毀所有已創(chuàng)建的bean,避免資源懸空
            // Destroy already created singletons to avoid dangling resources.
            destroyBeans();

            // 重置active標記為false
            // Reset 'active' flag.
            cancelRefresh(ex);

            // 將異常傳遞回調用者
            // Propagate exception to caller.
            throw ex;
        }

        finally {
            // 最后會將中間產生的一些緩存清除掉,這些緩存后期可能永遠都不會再被使用。
            // Reset common introspection caches in Spring's core, since we
            // might not ever need metadata for singleton beans anymore...
            resetCommonCaches();
        }
    }
}

這個方法包含了Spring IOC容器初始化的所有操作步驟。當我們讀懂了每一行代碼,就意味著我們了解了Spring IOC的所有功能。雖然該方法只有寥寥十多行,但是當下鉆到每個方法的內部,我們就會發(fā)現(xiàn)其調用層級之深,簡直令人發(fā)指,不過這并不能阻礙我們的鉆研。接下來,我們將深入分析每個方法內部的邏輯。

prepareRefresh方法

該方法用于準備上下文。

/**
 * Prepare this context for refreshing, setting its startup date and
 * active flag as well as performing any initialization of property sources.
 */
protected void prepareRefresh() {
    // Switch to active.
    // 設置開始時間,設置關閉標記為false,設置激活標記為true
    this.startupDate = System.currentTimeMillis();
    this.closed.set(false);
    this.active.set(true);

    // 簡單記錄一下日志
    if (logger.isDebugEnabled()) {
        if (logger.isTraceEnabled()) {
            logger.trace("Refreshing " + this);
        }
        else {
            logger.debug("Refreshing " + getDisplayName());
        }
    }

    // 在上下文環(huán)境中,初始化屬性源(例如:將帶占位符的屬性源進行替換),
    // 默認為空實現(xiàn)。
    // Initialize any placeholder property sources in the context environment.
    initPropertySources();

    // 在Environment中,校驗所有需要的屬性(如果那些標注為必需的屬性不存在的話,將拋出異常)
    // Validate that all properties marked as required are resolvable:
    // see ConfigurablePropertyResolver#setRequiredProperties
    getEnvironment().validateRequiredProperties();

    // 存儲(或者叫設置)預刷新的應用監(jiān)聽器,需要注意以下兩點:
    // 1. 如果`earlyApplicationListeners`不為空,說明用戶自定義過,那么將不需要使用`applicationListeners`進行覆蓋
    // 2. 如果`earlyApplicationListeners`為空,說明用戶未自定義過,那么需要根據(jù)`applicationListeners`進行設置
    // Store pre-refresh ApplicationListeners...
    if (this.earlyApplicationListeners == null) {
        this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
    }
    else {
        // Reset local application listeners to pre-refresh state.
        this.applicationListeners.clear();
        this.applicationListeners.addAll(this.earlyApplicationListeners);
    }

    // 設置初始的早期應用事件
    // Allow for the collection of early ApplicationEvents,
    // to be published once the multicaster is available...
    this.earlyApplicationEvents = new LinkedHashSet<>();
}

根據(jù)上面的源碼,我們知道這個方法主要做了以下幾件事情:

  1. 設置開始時間和激活標記;
  2. 校驗所有需要的屬性
  3. 初始化應用監(jiān)聽器及應用事件

obtainFreshBeanFactory方法

該方法用于獲取一個新鮮的bean工廠。那么,何為新鮮?

  1. 如果已經(jīng)存在一個bean工廠的話,需要先將其銷毀并關閉
  2. 創(chuàng)建一個新的bean工廠

那么其內部具體是怎么實現(xiàn)的呢?我們來分析下obtainFreshBeanFactory()方法。

/**
 * 先刷新,后獲取。
 * Tell the subclass to refresh the internal bean factory.
 * @return the fresh BeanFactory instance
 * @see #refreshBeanFactory()
 * @see #getBeanFactory()
 */
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
    refreshBeanFactory();
    return getBeanFactory();
}

refreshBeanFactory()方法:

/**
 * This implementation performs an actual refresh of this context's underlying
 * bean factory, shutting down the previous bean factory (if any) and
 * initializing a fresh bean factory for the next phase of the context's lifecycle.
 */
@Override
protected final void refreshBeanFactory() throws BeansException {
    // 如果bean工廠存在,那么銷毀所有的單例bean,并且關閉bean工廠
    if (hasBeanFactory()) {
        destroyBeans();
        closeBeanFactory();
    }
    try {
        // 創(chuàng)建bean工廠
        DefaultListableBeanFactory beanFactory = createBeanFactory();
        // 設置序列id
        beanFactory.setSerializationId(getId());
        // 自定義bean工廠
        customizeBeanFactory(beanFactory);
        // 加載BeanDefinitions
        loadBeanDefinitions(beanFactory);
        // 設置bean工廠
        synchronized (this.beanFactoryMonitor) {
            this.beanFactory = beanFactory;
        }
    }
    catch (IOException ex) {
        throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
    }
}

接下來我們分析下refreshBeanFactory()方法內部調用的方法,這些方法除了loadBeanDefinitions()比較復雜,其他都很簡單。

銷毀相關的方法如下:

/**
 * Determine whether this context currently holds a bean factory,
 * i.e. has been refreshed at least once and not been closed yet.
 */
protected final boolean hasBeanFactory() {
    synchronized (this.beanFactoryMonitor) {
        return (this.beanFactory != null);
    }
}

// 從這兒看出只是銷毀了所有的單例bean,其他scope的bean并沒有被銷毀
protected void destroyBeans() {
    getBeanFactory().destroySingletons();
}

// 關閉bean工廠,就是將bean工廠設置為null
protected final void closeBeanFactory() {
    synchronized (this.beanFactoryMonitor) {
        if (this.beanFactory != null) {
            this.beanFactory.setSerializationId(null);
            this.beanFactory = null;
        }
    }
}

createBeanFactory()方法,內部其實就是一個DefaultListableBeanFactory的實例。

protected DefaultListableBeanFactory createBeanFactory() {
    return new DefaultListableBeanFactory(getInternalParentBeanFactory());
}

customizeBeanFactory方法,選擇性地設置了兩個參數(shù):

  1. 允許bean定義被覆蓋
  2. 允許循環(huán)依賴
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
    if (this.allowBeanDefinitionOverriding != null) {
        beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
    }
    if (this.allowCircularReferences != null) {
        beanFactory.setAllowCircularReferences(this.allowCircularReferences);
    }
}

由于我們分析的入口是ClassPathXmlApplicationContext,因此Spring IOC管理的bean是從xml中加載過來的。我們分析的loadBeanDefinitions()方法,其內部應該也是如此。

最后有一個賦值語句this.beanFactory = beanFactory;,這說明ApplicationContext和BeanFactory的關系,最終還是組合的關系,這樣的好處就是松耦合,并且方便后續(xù)擴展和維護。

loadBeanDefinitions()

/**
 * Loads the bean definitions via an XmlBeanDefinitionReader.
 * @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader
 * @see #initBeanDefinitionReader
 * @see #loadBeanDefinitions
 */
@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
    // 通過bean工廠,實例化一個`XmlBeanDefinitionReader`,表示xml下BeanDefinition的讀取器
    // Create a new XmlBeanDefinitionReader for the given BeanFactory.
    XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

    // 配置bean定義讀取器,包括:環(huán)境對象、資源加載器、資源實體處理器
    // Configure the bean definition reader with this context's
    // resource loading environment.
    beanDefinitionReader.setEnvironment(this.getEnvironment());
    beanDefinitionReader.setResourceLoader(this);
    beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

    // Allow a subclass to provide custom initialization of the reader,
    // then proceed with actually loading the bean definitions.
    // 初始化
    initBeanDefinitionReader(beanDefinitionReader);
    // 加載
    loadBeanDefinitions(beanDefinitionReader);
}

initBeanDefinitionReader()用于初始化操作,主要設置校驗開關。

  1. 當校驗的時候,校驗模式設置為自動
  2. 當不校驗的時候,校驗模式設置為“不校驗”,同時設置命名空間驗證,這樣的話,就從側面進行了驗證。
protected void initBeanDefinitionReader(XmlBeanDefinitionReader reader) {
    reader.setValidating(this.validating);
}
/**
 * Set whether to use XML validation. Default is {@code true}.
 * <p>This method switches namespace awareness on if validation is turned off,
 * in order to still process schema namespaces properly in such a scenario.
 * @see #setValidationMode
 * @see #setNamespaceAware
 */
public void setValidating(boolean validating) {
    this.validationMode = (validating ? VALIDATION_AUTO : VALIDATION_NONE);
    this.namespaceAware = !validating;
}

重載的loadBeanDefinitions()方法傳入?yún)?shù)為reader。

protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
    Resource[] configResources = getConfigResources();
    if (configResources != null) {
        reader.loadBeanDefinitions(configResources);
    }
    String[] configLocations = getConfigLocations();
    if (configLocations != null) {
        reader.loadBeanDefinitions(configLocations);
    }
}

從上面的代碼我們看出,xml配置加載的方式有兩種,一種是以通用資源的方式,另一種是以配置位置的方式。配置位置的方式,最終將轉換為通用資源的方式。接下來,我們分析下配置位置的方式。

public int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException {
    Assert.notNull(locations, "Location array must not be null");
    int count = 0;
    for (String location : locations) {
        count += loadBeanDefinitions(location);
    }
    return count;
}

public int loadBeanDefinitions(String location) throws BeanDefinitionStoreException {
    return loadBeanDefinitions(location, null);
}

/**
 * Load bean definitions from the specified resource location.
 * <p>The location can also be a location pattern, provided that the
 * ResourceLoader of this bean definition reader is a ResourcePatternResolver.
 * @param location the resource location, to be loaded with the ResourceLoader
 * (or ResourcePatternResolver) of this bean definition reader
 * @param actualResources a Set to be filled with the actual Resource objects
 * that have been resolved during the loading process. May be {@code null}
 * to indicate that the caller is not interested in those Resource objects.
 * @return the number of bean definitions found
 * @throws BeanDefinitionStoreException in case of loading or parsing errors
 * @see #getResourceLoader()
 * @see #loadBeanDefinitions(org.springframework.core.io.Resource)
 * @see #loadBeanDefinitions(org.springframework.core.io.Resource[])
 */
public int loadBeanDefinitions(String location, @Nullable Set<Resource> actualResources) throws BeanDefinitionStoreException {
    ResourceLoader resourceLoader = getResourceLoader();
    if (resourceLoader == null) {
        throw new BeanDefinitionStoreException(
                "Cannot load bean definitions from location [" + location + "]: no ResourceLoader available");
    }

    if (resourceLoader instanceof ResourcePatternResolver) {
        // Resource pattern matching available.
        try {
            // 關鍵的代碼在這兒,通過資源加載器將配置位置轉換成了通用資源。
            Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);
            int count = loadBeanDefinitions(resources);
            if (actualResources != null) {
                Collections.addAll(actualResources, resources);
            }
            if (logger.isTraceEnabled()) {
                logger.trace("Loaded " + count + " bean definitions from location pattern [" + location + "]");
            }
            return count;
        }
        catch (IOException ex) {
            throw new BeanDefinitionStoreException(
                    "Could not resolve bean definition resource pattern [" + location + "]", ex);
        }
    }
    else {
        // Can only load single resources by absolute URL.
        Resource resource = resourceLoader.getResource(location);
        int count = loadBeanDefinitions(resource);
        if (actualResources != null) {
            actualResources.add(resource);
        }
        if (logger.isTraceEnabled()) {
            logger.trace("Loaded " + count + " bean definitions from location [" + location + "]");
        }
        return count;
    }
}

通用資源的BeanDefinition加載過程非常地復雜,因為xml配置支持的標簽非常多。限于篇幅,本文不做深入的分析。

在閱讀源碼的時候,樓主發(fā)現(xiàn)BeanDefinition有好幾個實現(xiàn)類,如下所示。我們著重分析紅框內的類。

圖片.png

他們的區(qū)別大致是這樣的。

  • AnnotatedBeanDefinition,包含有注解@Bean的Bean定義。一般情況下,通過注解的方式得到Bean定義,類型都是該接口的實現(xiàn)類。
  • AnnotatedGenericBeanDefinition,有@Configuration注解的類,會生成AnnotatedGenericBeanDefinition類型的Bean定義。
  • ScannedGenericBeanDefinition,有@Component注解的類,會生成ScannedGenericBeanDefinition類型的Bean定義。注意其它繼承了@Component的注解,同@Component
  • RootBeanDefinition、ChildBeanDefinitionGenericBeanDefinition,這幾個類均繼承了AbstractBeanDefinition。從官方文檔里,我們得到了以下一些信息:

RootBeanDefinition是最常用的實現(xiàn)類,它對應一般性的<bean>元素標簽,GenericBeanDefinition是自2.5以后新加入的bean文件配置屬性定義類,是一站式服務類。在配置文件中可以定義父<bean>子<bean>,父<bean>RootBeanDefinition表示,而子<bean>ChildBeanDefiniton表示,而沒有父<bean><bean>就使用RootBeanDefinition表示。AbstractBeanDefinition對兩者共同的類信息進行了抽象。

prepareBeanFactory方法

用于設置一些bean工廠相關的信息。例如:

  1. bean的類加載器、表達式處理、屬性編輯器注冊器
  2. 手動添加了一些bean后置處理器
  3. 指定某些依賴接口不被spring ioc容器所管理
  4. 手動注入一些關鍵的bean,例如bean工廠、應用上下文、環(huán)境相關的bean等等
/**
 * Configure the factory's standard context characteristics,
 * such as the context's ClassLoader and post-processors.
 * @param beanFactory the BeanFactory to configure
 */
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    // Tell the internal bean factory to use the context's class loader etc.
    // 設置bean的類加載器
    beanFactory.setBeanClassLoader(getClassLoader());
    // 設置bean的表達式處理器
    beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
    // 設置屬性編輯器注冊器
    beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

    // Configure the bean factory with context callbacks.
    // 添加bean后置處理器,用于給管理的bean設置“應用上下文”
    beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
    // 忽略依賴接口,凡是繼承這些接口的類實例將不會被spring ioc容器管理
    beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
    beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
    beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
    beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

    // BeanFactory interface not registered as resolvable type in a plain factory.
    // MessageSource registered (and found for autowiring) as a bean.
    // 手動注入`BeanFactory`、`ResourceLoader`、`ApplicationEventPublisher`和`ApplicationContext`。
    beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
    beanFactory.registerResolvableDependency(ResourceLoader.class, this);
    beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
    beanFactory.registerResolvableDependency(ApplicationContext.class, this);

    // Register early post-processor for detecting inner beans as ApplicationListeners.
    // 添加bean后置處理器,用于探測內部bean
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

    // Detect a LoadTimeWeaver and prepare for weaving, if found.
    // 添加bean后置處理器,用于AOP運行時織入
    if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
        beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
        // Set a temporary ClassLoader for type matching.
        beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }

    // Register default environment beans.
    // 注冊一些默認的環(huán)境相關的單例bean
    if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
        beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
    }
    if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
        beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
    }
    if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
        beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
    }
}

postProcessBeanFactory方法

該方法用于bean工廠加載后的后置處理,默認為空實現(xiàn)。

/**
 * Modify the application context's internal bean factory after its standard
 * initialization. All bean definitions will have been loaded, but no beans
 * will have been instantiated yet. This allows for registering special
 * BeanPostProcessors etc in certain ApplicationContext implementations.
 * @param beanFactory the bean factory used by the application context
 */
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
}

invokeBeanFactoryPostProcessors方法

該方法用于調用bean工廠的后置處理器(已注冊的)。

/**
 * Instantiate and invoke all registered BeanFactoryPostProcessor beans,
 * respecting explicit order if given.
 * <p>Must be called before singleton instantiation.
 */
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

    // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
    // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
    // 運行時切面織入相關的配置
    if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
        beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
        beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }
}

PostProcessorRegistrationDelegate是一個工具類,其下的invokeBeanFactoryPostProcessors方法非常復雜。為啥會這么復雜,主要是由于以下幾個方面:

  1. BeanFactoryPostProcessor可以被配置;
  2. BeanFactoryPostProcessor有一個特殊的子類BeanDefinitionRegistryPostProcessor,其用途就是方便BeanFactoryPostProcessor可以靈活地配置;
  3. BeanFactoryPostProcessor可以定義優(yōu)先級、順序性,以及無順序性。

接下來,我們具體看看源代碼。

// 該類是final修飾,說明其不可繼承。同時其構造器是私有的,說明不能被實例化。因此其就是一個靜態(tài)工具類。
final class PostProcessorRegistrationDelegate {

    private PostProcessorRegistrationDelegate() {
    }

    public static void invokeBeanFactoryPostProcessors(
            ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

        // Invoke BeanDefinitionRegistryPostProcessors first, if any.
        Set<String> processedBeans = new HashSet<>();

        // 因為beanFactory的默認實現(xiàn)為`DefaultListableBeanFactory`,所以本身就繼承了`BeanDefinitionRegistry`。
        // 這兒,我們僅分析if語句塊就可以了。
        if (beanFactory instanceof BeanDefinitionRegistry) {
            // bean工廠就是`BeanDefinitionRegistry`
            BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
            // 分離出標準的后置處理器,以及注冊器后置處理器
            List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
            List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

            for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
                if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                    BeanDefinitionRegistryPostProcessor registryProcessor =
                            (BeanDefinitionRegistryPostProcessor) postProcessor;
                    registryProcessor.postProcessBeanDefinitionRegistry(registry);
                    registryProcessors.add(registryProcessor);
                }
                else {
                    regularPostProcessors.add(postProcessor);
                }
            }

            // Do not initialize FactoryBeans here: We need to leave all regular beans
            // uninitialized to let the bean factory post-processors apply to them!
            // Separate between BeanDefinitionRegistryPostProcessors that implement
            // PriorityOrdered, Ordered, and the rest.
            // 1. 工廠bean不會被實例化
            // 2. 優(yōu)先處理注冊器后置處理器
            List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

            // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
            // 第一步,處理實現(xiàn)了`PriorityOrdered`接口的`BeanDefinitionRegistryPostProcessor`,包括:
            // 1. 排序
            // 2. 添加到`registryProcessors`,方便后續(xù)統(tǒng)一處理
            // 3. 調用`postProcessBeanDefinitionRegistry`方法
            // 4. 清理currentRegistryProcessors,方便后續(xù)復用
            String[] postProcessorNames =
                    beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            for (String ppName : postProcessorNames) {
                if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    processedBeans.add(ppName);
                }
            }
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            registryProcessors.addAll(currentRegistryProcessors);
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            currentRegistryProcessors.clear();

            // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
            // 第二步,處理實現(xiàn)了`Ordered`接口的`BeanDefinitionRegistryPostProcessor`,處理步驟和第一步相同
            postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            for (String ppName : postProcessorNames) {
                if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    processedBeans.add(ppName);
                }
            }
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            registryProcessors.addAll(currentRegistryProcessors);
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            currentRegistryProcessors.clear();

            // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
            // 最終,調用所有除了實現(xiàn)`PriorityOrdered`和`Ordered`的`BeanDefinitionRegistryPostProcessors`,
            // 處理步驟和第一步相同
            // 注意,這兒使用了while循環(huán),而不是if,樓主也不知道是為什么
            boolean reiterate = true;
            while (reiterate) {
                reiterate = false;
                postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
                for (String ppName : postProcessorNames) {
                    if (!processedBeans.contains(ppName)) {
                        currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                        processedBeans.add(ppName);
                        reiterate = true;
                    }
                }
                sortPostProcessors(currentRegistryProcessors, beanFactory);
                registryProcessors.addAll(currentRegistryProcessors);
                invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
                currentRegistryProcessors.clear();
            }

            // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
            // OK,上面的都做完了,就可以開始調用bean工廠的后置處理器了
            invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
            invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
        }

        else {
            // Invoke factory processors registered with the context instance.
            invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
        }

        // Do not initialize FactoryBeans here: We need to leave all regular beans
        // uninitialized to let the bean factory post-processors apply to them!
        // 除了上面的bean工廠后置處理器,我們還可以自己配置一些bean工廠后置處理器,例如:
        // 1. 在xml中通過<bean>的方式
        // 2. 在java config中通過@Bean的方式
        // 3. 在自動裝配中通過@Componet的方式
        // 因此,在這兒我們需要對這些后置處理器進行處理。
        // 同樣地,根據(jù)是否是`PriorityOrdered`、`Ordered`,會有特殊的處理。
        String[] postProcessorNames =
                beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

        // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
        // Ordered, and the rest.
        List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
        List<String> orderedPostProcessorNames = new ArrayList<>();
        List<String> nonOrderedPostProcessorNames = new ArrayList<>();
        for (String ppName : postProcessorNames) {
            if (processedBeans.contains(ppName)) {
                // skip - already processed in first phase above
            }
            else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
            }
            else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
                orderedPostProcessorNames.add(ppName);
            }
            else {
                nonOrderedPostProcessorNames.add(ppName);
            }
        }

        // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
        sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
        invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

        // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
        List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
        for (String postProcessorName : orderedPostProcessorNames) {
            orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
        }
        sortPostProcessors(orderedPostProcessors, beanFactory);
        invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

        // Finally, invoke all other BeanFactoryPostProcessors.
        List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
        for (String postProcessorName : nonOrderedPostProcessorNames) {
            nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
        }
        invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

        // Clear cached merged bean definitions since the post-processors might have
        // modified the original metadata, e.g. replacing placeholders in values...
        beanFactory.clearMetadataCache();
    }
}

registerBeanPostProcessors方法

該方法用于注冊bean后置處理器,最終調用的仍然是PostProcessorRegistrationDelegate中的工具方法,我們來看一下。

protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}

public static void registerBeanPostProcessors(
        ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

    String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

    // Register BeanPostProcessorChecker that logs an info message when
    // a bean is created during BeanPostProcessor instantiation, i.e. when
    // a bean is not eligible for getting processed by all BeanPostProcessors.
    // 這兒會做兩件事情:
    // 1. 統(tǒng)計bean后置處理器的個數(shù),格式是根據(jù)以下地方進行統(tǒng)計的
    //     1. bean工廠內部的
    //     2. 隨后添加的一個檢查bean后置處理器
    //     3. 用戶自己定義的
    // 2. 添加一個bean后置處理器,用于檢查目的,當檢查不通過時,將記錄info級別的日志
    int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
    beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

    // Separate between BeanPostProcessors that implement PriorityOrdered,
    // Ordered, and the rest.
    // 分離出`PriorityOrdered`、`Ordered`和剩下的bean后置處理器
    List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
    List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
    List<String> orderedPostProcessorNames = new ArrayList<>();
    List<String> nonOrderedPostProcessorNames = new ArrayList<>();
    for (String ppName : postProcessorNames) {
        if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
            BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
            priorityOrderedPostProcessors.add(pp);
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                internalPostProcessors.add(pp);
            }
        }
        else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
            orderedPostProcessorNames.add(ppName);
        }
        else {
            nonOrderedPostProcessorNames.add(ppName);
        }
    }

    // First, register the BeanPostProcessors that implement PriorityOrdered.
    // 第一步,排序并重新注冊到bean工廠(PriorityOrdered)
    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

    // Next, register the BeanPostProcessors that implement Ordered.
    // 第二步,排序并重新注冊到bean工廠(Ordered)
    List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
    for (String ppName : orderedPostProcessorNames) {
        BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
        orderedPostProcessors.add(pp);
        if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
        }
    }
    sortPostProcessors(orderedPostProcessors, beanFactory);
    registerBeanPostProcessors(beanFactory, orderedPostProcessors);

    // Now, register all regular BeanPostProcessors.
    // 第三步,注冊剩余的到bean工廠
    List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
    for (String ppName : nonOrderedPostProcessorNames) {
        BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
        nonOrderedPostProcessors.add(pp);
        if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
        }
    }
    registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

    // Finally, re-register all internal BeanPostProcessors.
    // 最后一步,重新注冊內部的到bean工廠,目的是將他們排序到最后位置
    sortPostProcessors(internalPostProcessors, beanFactory);
    registerBeanPostProcessors(beanFactory, internalPostProcessors);

    // Re-register post-processor for detecting inner beans as ApplicationListeners,
    // moving it to the end of the processor chain (for picking up proxies etc).
    // 添加一個事件監(jiān)聽的bean后置處理器,但是不納入bean后置處理器個數(shù)的統(tǒng)計
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

initMessageSource方法

該方法用于初始化消息源。所謂消息源,是為了支持國際化而服務的,本文我們不會過多地對此進行分析。

initApplicationEventMulticaster方法

該方法用于初始化應用事件廣播器。

/**
 * Initialize the ApplicationEventMulticaster.
 * Uses SimpleApplicationEventMulticaster if none defined in the context.
 * @see org.springframework.context.event.SimpleApplicationEventMulticaster
 */
protected void initApplicationEventMulticaster() {
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    // 如果bean工廠包含應用事件廣播器,那么就使用它
    // 否則,使用`SimpleApplicationEventMulticaster`創(chuàng)建一個默認的應用事件廣播器
    if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
        this.applicationEventMulticaster =
                beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
        if (logger.isTraceEnabled()) {
            logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
        }
    }
    else {
        this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
        beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
        if (logger.isTraceEnabled()) {
            logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
                    "[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
        }
    }
}

onRefresh方法

該方法用于初始化其他特殊的bean,默認為空實現(xiàn)

registerListeners方法

用于注冊應用監(jiān)聽器到應用事件廣播器中。

/**
 * Add beans that implement ApplicationListener as listeners.
 * Doesn't affect other listeners, which can be added without being beans.
 */
protected void registerListeners() {
    // Register statically specified listeners first.
    // 注冊靜態(tài)的監(jiān)聽器
    for (ApplicationListener<?> listener : getApplicationListeners()) {
        getApplicationEventMulticaster().addApplicationListener(listener);
    }

    // Do not initialize FactoryBeans here: We need to leave all regular beans
    // uninitialized to let post-processors apply to them!
    // 注冊自定義的監(jiān)聽器
    String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
    for (String listenerBeanName : listenerBeanNames) {
        getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
    }

    // Publish early application events now that we finally have a multicaster...
    // 對預設置的事件進行廣播
    Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
    this.earlyApplicationEvents = null;
    if (earlyEventsToProcess != null) {
        for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
            getApplicationEventMulticaster().multicastEvent(earlyEvent);
        }
    }
}

finishBeanFactoryInitialization方法

用于實例化所有剩余的非懶加載的單例bean。

/**
 * Finish the initialization of this context's bean factory,
 * initializing all remaining singleton beans.
 */
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
    // Initialize conversion service for this context.
    // 初始化轉換服務
    if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
            beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
        beanFactory.setConversionService(
                beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
    }

    // Register a default embedded value resolver if no bean post-processor
    // (such as a PropertyPlaceholderConfigurer bean) registered any before:
    // at this point, primarily for resolution in annotation attribute values.
    // 如果沒有嵌套值處理器,那么注冊一個默認的嵌套值處理器
    if (!beanFactory.hasEmbeddedValueResolver()) {
        beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
    }

    // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
    // 初始化運行時織入的bean
    String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
    for (String weaverAwareName : weaverAwareNames) {
        getBean(weaverAwareName);
    }

    // Stop using the temporary ClassLoader for type matching.
    // 停止臨時的類加載器
    beanFactory.setTempClassLoader(null);

    // Allow for caching all bean definition metadata, not expecting further changes.
    // 凍結配置(即:配置不可再被修改)
    beanFactory.freezeConfiguration();

    // Instantiate all remaining (non-lazy-init) singletons.
    // 調用工廠方法`preInstantiateSingletons`,預實例化所有的單例bean。
    // 該方法非常關鍵,其內部解決循環(huán)依賴問題的思路非常有意思。
    beanFactory.preInstantiateSingletons();
}

preInstantiateSingletons方法

該方法用于初始化所有的單例bean,其最最核心和關鍵的內容在于使用三級緩存解決循環(huán)依賴的問題。

那么,Spring為什么能解決循環(huán)依賴的問題呢?網(wǎng)上有很多這方面的分析,各種前因后果,細細道來冗長而繁瑣。

為了便于理解,樓主直接說結果。能解決的根本原因在于引用傳遞。對象初始化之后,其引用就已經(jīng)確定下來了,后期也不會再變化,因此引用可以被其他地方使用。我們可以將初始化的過程分成兩個階段:

  1. 構造器創(chuàng)建對象(創(chuàng)建a對象,傳播b對象)
  2. 設置依賴關系(給a對象設置b對象引用,給b對象設置a對象引用)

在此基礎上,Spring衍生出了三級緩存,其僅支持單例的循環(huán)依賴。

  1. 不能解決的情況:
    1. 構造器注入循環(huán)依賴
    2. prototype field屬性注入(或者setter方法注入)循環(huán)依賴
  2. 能解決的情況:
    1. field屬性注入(或者setter方法注入)循環(huán)依賴

好了,步入正軌,我們開始分析這個方法。

public void preInstantiateSingletons() throws BeansException {
    // 簡單記錄一下跟蹤日志
    if (logger.isTraceEnabled()) {
        logger.trace("Pre-instantiating singletons in " + this);
    }

    // Iterate over a copy to allow for init methods which in turn register new bean definitions.
    // While this may not be part of the regular factory bootstrap, it does otherwise work fine.
    // bean定義的名稱,就是bean的名稱
    List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

    // Trigger initialization of all non-lazy singleton beans...
    for (String beanName : beanNames) {
        // 合并bean定義
        RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
        // 只有非抽象的、單例的、非懶加載的bean定義,才會實例化成bean,并注冊到bean工廠
        if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
            // 1. 如果是工廠bean,同時為預加載的話,那么直接調用`getBean`方法加載bean
            // 2. 如果不是工廠bean,直接調用`getBean`方法加載bean
            if (isFactoryBean(beanName)) {
                Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
                if (bean instanceof FactoryBean) {
                    final FactoryBean<?> factory = (FactoryBean<?>) bean;
                    boolean isEagerInit;
                    if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                        isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
                                        ((SmartFactoryBean<?>) factory)::isEagerInit,
                                getAccessControlContext());
                    }
                    else {
                        isEagerInit = (factory instanceof SmartFactoryBean &&
                                ((SmartFactoryBean<?>) factory).isEagerInit());
                    }
                    if (isEagerInit) {
                        getBean(beanName);
                    }
                }
            }
            else {
                getBean(beanName);
            }
        }
    }

    // Trigger post-initialization callback for all applicable beans...
    // bean加載之后,如果bean為`SmartInitializingSingleton`類型,那么將觸發(fā)方法`afterSingletonsInstantiated()`
    for (String beanName : beanNames) {
        Object singletonInstance = getSingleton(beanName);
        if (singletonInstance instanceof SmartInitializingSingleton) {
            final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
            if (System.getSecurityManager() != null) {
                AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                    smartSingleton.afterSingletonsInstantiated();
                    return null;
                }, getAccessControlContext());
            }
            else {
                smartSingleton.afterSingletonsInstantiated();
            }
        }
    }
}

getBean()方法至關重要,用于獲取一個bean。其調用的是doGetBean()方法,根據(jù)名稱獲取一個bean。

public Object getBean(String name) throws BeansException {
    return doGetBean(name, null, null, false);
}

接下來,我們分析一下doGetBean()方法。

/**
 * Return an instance, which may be shared or independent, of the specified bean.
 * @param name the name of the bean to retrieve
 * @param requiredType the required type of the bean to retrieve
 * @param args arguments to use when creating a bean instance using explicit arguments
 * (only applied when creating a new instance as opposed to retrieving an existing one)
 * @param typeCheckOnly whether the instance is obtained for a type check,
 * not for actual use
 * @return an instance of the bean
 * @throws BeansException if the bean could not be created
 */
@SuppressWarnings("unchecked")
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
        @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

    // 獲取bean最初的名稱,因為傳入的bean名稱可能是一個別名,也可能是一個工廠bean的名稱
    final String beanName = transformedBeanName(name);
    Object bean;

    // Eagerly check singleton cache for manually registered singletons.
    // 這兒嘗試從三級緩存獲取單例對象
    Object sharedInstance = getSingleton(beanName);
    if (sharedInstance != null && args == null) {
        if (logger.isTraceEnabled()) {
            if (isSingletonCurrentlyInCreation(beanName)) {
                logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
                        "' that is not fully initialized yet - a consequence of a circular reference");
            }
            else {
                logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
            }
        }
        // 從三級緩存獲取到之后,將嘗試將bean手動注冊到bean工廠
        bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    }

    else {
        // Fail if we're already creating this bean instance:
        // We're assumably within a circular reference.
        // 如果三級緩存沒獲取到,且bean為prototype類型,那么拋出異常
        if (isPrototypeCurrentlyInCreation(beanName)) {
            throw new BeanCurrentlyInCreationException(beanName);
        }

        // Check if bean definition exists in this factory.
        // 如果當前bean工廠不包含bean的定義,則委托給父工廠進行get處理
        BeanFactory parentBeanFactory = getParentBeanFactory();
        if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
            // Not found -> check parent.
            String nameToLookup = originalBeanName(name);
            if (parentBeanFactory instanceof AbstractBeanFactory) {
                return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
                        nameToLookup, requiredType, args, typeCheckOnly);
            }
            else if (args != null) {
                // Delegation to parent with explicit args.
                return (T) parentBeanFactory.getBean(nameToLookup, args);
            }
            else if (requiredType != null) {
                // No args -> delegate to standard getBean method.
                return parentBeanFactory.getBean(nameToLookup, requiredType);
            }
            else {
                return (T) parentBeanFactory.getBean(nameToLookup);
            }
        }

        // 如果不僅僅是類型檢查,那么將beanName放入已創(chuàng)建的bean名稱集合里面
        if (!typeCheckOnly) {
            markBeanAsCreated(beanName);
            // 這就是上面方法的實現(xiàn)
            /*
            protected void markBeanAsCreated(String beanName) {
                if (!this.alreadyCreated.contains(beanName)) {
                    synchronized (this.mergedBeanDefinitions) {
                        if (!this.alreadyCreated.contains(beanName)) {
                            // Let the bean definition get re-merged now that we're actually creating
                            // the bean... just in case some of its metadata changed in the meantime.
                            clearMergedBeanDefinition(beanName);
                            this.alreadyCreated.add(beanName);
                        }
                    }
                }
            }
            */
        }

        try {
            // 獲取合并的bean定義,并檢查(這兒判斷是否為abstract)
            final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
            checkMergedBeanDefinition(mbd, beanName, args);

            // Guarantee initialization of beans that the current bean depends on.
            // 這兒會判斷是否存在構造器的循環(huán)依賴,如果存在則拋出異常,否則的話就先注冊依賴關系,再get這個bean
            String[] dependsOn = mbd.getDependsOn();
            if (dependsOn != null) {
                for (String dep : dependsOn) {
                    if (isDependent(beanName, dep)) {
                        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
                    }
                    registerDependentBean(dep, beanName);
                    try {
                        getBean(dep);
                    }
                    catch (NoSuchBeanDefinitionException ex) {
                        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
                    }
                }
            }

            // Create bean instance.
            // 創(chuàng)建單例
            if (mbd.isSingleton()) {
                // 創(chuàng)建單例的時候,會傳入一個ObjectFactory的對象。首先它是一個工廠,然后他會創(chuàng)一個對象。
                sharedInstance = getSingleton(beanName, () -> {
                    try {
                        return createBean(beanName, mbd, args);
                    }
                    catch (BeansException ex) {
                        // Explicitly remove instance from singleton cache: It might have been put there
                        // eagerly by the creation process, to allow for circular reference resolution.
                        // Also remove any beans that received a temporary reference to the bean.
                        destroySingleton(beanName);
                        throw ex;
                    }
                });
                // 獲取到bean的時候,為啥不直接返回,原因在于獲取到的bean可能是一個工廠bean,工廠bean又可能是工廠bean的工廠bean。
                // 因此,這個方法就是解決這個問題而存在的。
                bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
            }
            
            // 創(chuàng)建prototype
            else if (mbd.isPrototype()) {
                // It's a prototype -> create a new instance.
                Object prototypeInstance = null;
                try {
                    beforePrototypeCreation(beanName);
                    prototypeInstance = createBean(beanName, mbd, args);
                }
                finally {
                    afterPrototypeCreation(beanName);
                }
                bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
            }

            // 創(chuàng)建其他Scope
            else {
                String scopeName = mbd.getScope();
                final Scope scope = this.scopes.get(scopeName);
                if (scope == null) {
                    throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
                }
                try {
                    Object scopedInstance = scope.get(beanName, () -> {
                        beforePrototypeCreation(beanName);
                        try {
                            return createBean(beanName, mbd, args);
                        }
                        finally {
                            afterPrototypeCreation(beanName);
                        }
                    });
                    bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
                }
                catch (IllegalStateException ex) {
                    throw new BeanCreationException(beanName,
                            "Scope '" + scopeName + "' is not active for the current thread; consider " +
                            "defining a scoped proxy for this bean if you intend to refer to it from a singleton",
                            ex);
                }
            }
        }
        catch (BeansException ex) {
            cleanupAfterBeanCreationFailure(beanName);
            throw ex;
        }
    }

    // Check if required type matches the type of the actual bean instance.
    // 如果類型不匹配,則需要通過轉換器進行轉換。當轉換不成功,則拋出異常。
    if (requiredType != null && !requiredType.isInstance(bean)) {
        try {
            T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
            if (convertedBean == null) {
                throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
            }
            return convertedBean;
        }
        catch (TypeMismatchException ex) {
            if (logger.isTraceEnabled()) {
                logger.trace("Failed to convert bean '" + name + "' to required type '" +
                        ClassUtils.getQualifiedName(requiredType) + "'", ex);
            }
            throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
        }
    }
    return (T) bean;
}

重點來了!

在分析完doGetBean()方法后,我們發(fā)現(xiàn)不管是當前bean,還是依賴的bean,最終調用的都是getSingleton()方法。該方法有好幾個重載方法,我們依次來分析。

/** Cache of singleton objects: bean name to bean instance. */
// 一級緩存,緩存已實例化的bean
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

/** Cache of early singleton objects: bean name to bean instance. */
// 二級緩存,緩存`early`(可提前暴露)的bean
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);

/** Cache of singleton factories: bean name to ObjectFactory. */
// 三級緩存,緩存對象工廠對象
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

/** Set of registered singletons, containing the bean names in registration order. */
// 已注冊的單例bean名稱
private final Set<String> registeredSingletons = new LinkedHashSet<>(256);

/** Names of beans that are currently in creation. */
// 當前正在創(chuàng)建的單例bean名稱
private final Set<String> singletonsCurrentlyInCreation =
        Collections.newSetFromMap(new ConcurrentHashMap<>(16));

// 調用的是下面那個方法,且參數(shù)`allowEarlyReference`為true
public Object getSingleton(String beanName) {
    return getSingleton(beanName, true);
}

protected Object getSingleton(String beanName, boolean allowEarlyReference) {
    // 1. 先從一級緩存`singletonObjects`中去獲取。(如果獲取到就直接return)
    Object singletonObject = this.singletonObjects.get(beanName);
    if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
        synchronized (this.singletonObjects) {
            // 2. 如果獲取不到或者對象正在創(chuàng)建中(isSingletonCurrentlyInCreation()),那就再從二級緩存earlySingletonObjects中獲取。(如果獲取到就直接return)
            singletonObject = this.earlySingletonObjects.get(beanName);
            if (singletonObject == null && allowEarlyReference) {
                // 3. 如果還是獲取不到,且允許`singletonFactories`(`allowEarlyReference = true`)通過`getObject()`獲取。
                // 就從三級緩存`singletonFactory.getObject()`獲取。
                // (如果獲取到了就從`singletonFactories`中移除,并且放進`earlySingletonObjects`。
                // 其實也就是從三級緩存移動(是剪切、不是復制哦~)到了二級緩存)
                ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                if (singletonFactory != null) {
                    singletonObject = singletonFactory.getObject();
                    this.earlySingletonObjects.put(beanName, singletonObject);
                    this.singletonFactories.remove(beanName);
                }
            }
        }
    }
    return singletonObject;
}

/**
 * 相比較于上個方法,多了錯誤校驗、異常處理、外置化`ObjectFactory`創(chuàng)建對象的操作。
 * Return the (raw) singleton object registered under the given name,
 * creating and registering a new one if none registered yet.
 * @param beanName the name of the bean
 * @param singletonFactory the ObjectFactory to lazily create the singleton
 * with, if necessary
 * @return the registered singleton object
 */
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
    Assert.notNull(beanName, "Bean name must not be null");
    synchronized (this.singletonObjects) {
        Object singletonObject = this.singletonObjects.get(beanName);
        if (singletonObject == null) {
            if (this.singletonsCurrentlyInDestruction) {
                throw new BeanCreationNotAllowedException(beanName,
                        "Singleton bean creation not allowed while singletons of this factory are in destruction " +
                        "(Do not request a bean from a BeanFactory in a destroy method implementation!)");
            }
            if (logger.isDebugEnabled()) {
                logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
            }
            beforeSingletonCreation(beanName);
            boolean newSingleton = false;
            boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
            if (recordSuppressedExceptions) {
                this.suppressedExceptions = new LinkedHashSet<>();
            }
            try {
                singletonObject = singletonFactory.getObject();
                newSingleton = true;
            }
            catch (IllegalStateException ex) {
                // Has the singleton object implicitly appeared in the meantime ->
                // if yes, proceed with it since the exception indicates that state.
                singletonObject = this.singletonObjects.get(beanName);
                if (singletonObject == null) {
                    throw ex;
                }
            }
            catch (BeanCreationException ex) {
                if (recordSuppressedExceptions) {
                    for (Exception suppressedException : this.suppressedExceptions) {
                        ex.addRelatedCause(suppressedException);
                    }
                }
                throw ex;
            }
            finally {
                if (recordSuppressedExceptions) {
                    this.suppressedExceptions = null;
                }
                afterSingletonCreation(beanName);
            }
            if (newSingleton) {
                addSingleton(beanName, singletonObject);
            }
        }
        return singletonObject;
    }
}

簡單總結一下,Spring解決循環(huán)依賴的三級緩存邏輯如下:

  1. 先從一級緩存singletonObjects中去獲取。(如果獲取到就直接return)
  2. 如果獲取不到或者對象正在創(chuàng)建中(isSingletonCurrentlyInCreation()),那就再從二級緩存earlySingletonObjects中獲取。(如果獲取到就直接return)
  3. 如果還是獲取不到,且允許singletonFactoriesallowEarlyReference = true)通過getObject()獲取。就從三級緩存singletonFactory.getObject()獲取。(如果獲取到了就從singletonFactories中移除,并且放進earlySingletonObjects。其實也就是從三級緩存移動(是剪切、不是復制哦~)到了二級緩存)。

生命周期

在分析finishRefresh()方法之前,我們有必要澄清一下,何為生命周期?

所謂生命周期,其實是一系列的回調。包括:

  1. Initialization callbacks(初始化回調)
  2. Destruction callbacks(銷毀回調)

要與容器的bean生命周期管理交互,即容器在啟動后和容器在銷毀前對每個bean執(zhí)行操作,有如下三種方法:

  1. 實現(xiàn)Spring框架的InitializingBeanDisposableBean接口。容器為前者調用afterPropertiesSet()方法,為后者調用destroy()方法,以允許bean在初始化和銷毀的時候執(zhí)行某些操作。
public class HelloLifeCycle implements InitializingBean, DisposableBean {
    
    public void afterPropertiesSet() throws Exception {
        System.out.println("afterPropertiesSet 啟動");
    }

    public void destroy() throws Exception {
        System.out.println("DisposableBean 停止");
    }
}
  1. 在xml配置中,bean在定義的時候,指定初始化方法和銷毀方法。
 <bean id="helloLifeCycle" class="com.hzways.life.cycle.HelloLifeCycle" init-method="init3" destroy-method="destroy3"/>
  1. JSR-250中,@PostConstruct@PreDestroy注解,可用于bean的初始化后和銷毀前操作。
  • @PostConstruct注解用于方法上,該方法在初始化完成之后被執(zhí)行。
  • @PreDestroy注解用于方法上,該方法在銷毀前被執(zhí)行。
@Service
public class HelloLifeCycle {

    @PostConstruct
    private void init2() {
        System.out.println("PostConstruct 啟動");
    }

    @PreDestroy
    private void destroy2() {
        System.out.println("PreDestroy 停止");
    }
}

finishRefresh方法

該方法主要調用了生命周期處理器的onRefresh()方法。

/**
 * Finish the refresh of this context, invoking the LifecycleProcessor's
 * onRefresh() method and publishing the
 * {@link org.springframework.context.event.ContextRefreshedEvent}.
 */
protected void finishRefresh() {
    // Clear context-level resource caches (such as ASM metadata from scanning).
    // 清除上下文級別的資源緩存
    clearResourceCaches();

    // Initialize lifecycle processor for this context.
    // 初始化生命周期處理器
    initLifecycleProcessor();

    // Propagate refresh to lifecycle processor first.
    // 傳播刷新操作到聲明周期處理器
    getLifecycleProcessor().onRefresh();

    // Publish the final event.
    // 發(fā)布事件
    publishEvent(new ContextRefreshedEvent(this));

    // Participate in LiveBeansView MBean, if active.
    // MBean管理相關
    LiveBeansView.registerApplicationContext(this);
}

這兒我們著重關注兩個方法:initLifecycleProcessor()getLifecycleProcessor().onRefresh()。

initLifecycleProcessor方法

該方法很簡單。

  1. 首先嘗試從bean工廠獲取生命周期處理器;
  2. 如果bean工廠未獲取到,初始化一個默認的生命周期處理器(DefaultLifecycleProcessor),并注冊到bean工廠;
  3. 在前面兩部的基礎上,設置處理到AbstractApplicationContext的成員變量lifecycleProcessor上,供后續(xù)使用。
/**
 * Initialize the LifecycleProcessor.
 * Uses DefaultLifecycleProcessor if none defined in the context.
 * @see org.springframework.context.support.DefaultLifecycleProcessor
 */
protected void initLifecycleProcessor() {
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
        this.lifecycleProcessor =
                beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
        if (logger.isTraceEnabled()) {
            logger.trace("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");
        }
    }
    else {
        DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
        defaultProcessor.setBeanFactory(beanFactory);
        this.lifecycleProcessor = defaultProcessor;
        beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
        if (logger.isTraceEnabled()) {
            logger.trace("No '" + LIFECYCLE_PROCESSOR_BEAN_NAME + "' bean, using " +
                    "[" + this.lifecycleProcessor.getClass().getSimpleName() + "]");
        }
    }
}

onRefresh方法

分析該方法前,先看看getLifecycleProcessor(),其實就是檢查并返回成員變量lifecycleProcessor。

LifecycleProcessor getLifecycleProcessor() throws IllegalStateException {
    if (this.lifecycleProcessor == null) {
        throw new IllegalStateException("LifecycleProcessor not initialized - " +
                "call 'refresh' before invoking lifecycle methods via the context: " + this);
    }
    return this.lifecycleProcessor;
}
public void onRefresh() {
    startBeans(true);
    this.running = true;
}

onRefresh()方法調用了startBeans方法,之后更新了運行狀態(tài)。

private void startBeans(boolean autoStartupOnly) {
    // 獲取所有Bean工廠管理的`Lifecycle`對象
    Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();
    Map<Integer, LifecycleGroup> phases = new HashMap<>();
    // 根據(jù)`phase`進行分組
    lifecycleBeans.forEach((beanName, bean) -> {
        if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) {
            int phase = getPhase(bean);
            LifecycleGroup group = phases.get(phase);
            if (group == null) {
                group = new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly);
                phases.put(phase, group);
            }
            group.add(beanName, bean);
        }
    });
    // 根據(jù)分組,調用對象的`start()`方法
    if (!phases.isEmpty()) {
        List<Integer> keys = new ArrayList<>(phases.keySet());
        Collections.sort(keys);
        for (Integer key : keys) {
            phases.get(key).start();
        }
    }
}

startBeans()方法做了以下事情:

  1. 首先獲取所有Bean工廠管理的Lifecycle對象;
  2. Lifecycle對象根據(jù)phase(階段的意思,其實是一個int值)進行分組。相同phase的對象劃到一個組;
  3. 根據(jù)phase的值大小,升序調用其Lifecycle對象的start()方法。

getLifecycleBeans()方法用于獲取對象。

/**
 * Retrieve all applicable Lifecycle beans: all singletons that have already been created,
 * as well as all SmartLifecycle beans (even if they are marked as lazy-init).
 * @return the Map of applicable beans, with bean names as keys and bean instances as values
 */
protected Map<String, Lifecycle> getLifecycleBeans() {
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    Map<String, Lifecycle> beans = new LinkedHashMap<>();
    // 獲取所有類型為`Lifecycle`的bean名稱
    String[] beanNames = beanFactory.getBeanNamesForType(Lifecycle.class, false, false);
    for (String beanName : beanNames) {
        String beanNameToRegister = BeanFactoryUtils.transformedBeanName(beanName);
        boolean isFactoryBean = beanFactory.isFactoryBean(beanNameToRegister);
        String beanNameToCheck = (isFactoryBean ? BeanFactory.FACTORY_BEAN_PREFIX + beanName : beanName);
        // 這兒對bean加了一些限制條件
        // 1. 如果是單例的話,不能是工廠bean,且類型必須為`Lifecycle`
        // 2. 如果不是單例的話,類型必須為`SmartLifecycle`
        if ((beanFactory.containsSingleton(beanNameToRegister) &&
                (!isFactoryBean || matchesBeanType(Lifecycle.class, beanNameToCheck, beanFactory))) ||
                matchesBeanType(SmartLifecycle.class, beanNameToCheck, beanFactory)) {
            Object bean = beanFactory.getBean(beanNameToCheck);
            if (bean != this && bean instanceof Lifecycle) {
                beans.put(beanNameToRegister, (Lifecycle) bean);
            }
        }
    }
    return beans;
}

最關鍵的地方在于start()方法的調用。

public void start() {
    if (this.members.isEmpty()) {
        return;
    }
    if (logger.isDebugEnabled()) {
        logger.debug("Starting beans in phase " + this.phase);
    }
    // 對分組內的bean按照名稱進行排序,并最終調用了`doStart()`方法
    Collections.sort(this.members);
    for (LifecycleGroupMember member : this.members) {
        doStart(this.lifecycleBeans, member.name, this.autoStartupOnly);
    }
}

/**
 * Start the specified bean as part of the given set of Lifecycle beans,
 * making sure that any beans that it depends on are started first.
 * @param lifecycleBeans a Map with bean name as key and Lifecycle instance as value
 * @param beanName the name of the bean to start
 */
private void doStart(Map<String, ? extends Lifecycle> lifecycleBeans, String beanName, boolean autoStartupOnly) {
    Lifecycle bean = lifecycleBeans.remove(beanName);
    if (bean != null && bean != this) {
        String[] dependenciesForBean = getBeanFactory().getDependenciesForBean(beanName);
        for (String dependency : dependenciesForBean) {
            // 這兒有遞歸調用。
            // 需要特別注意的地方在于,如果一個`Lifecycle`依賴另外一個`Lifecycle`,則會優(yōu)先調用被依賴的`Lifecycle`。
            doStart(lifecycleBeans, dependency, autoStartupOnly);
        }
        if (!bean.isRunning() &&
                (!autoStartupOnly || !(bean instanceof SmartLifecycle) || ((SmartLifecycle) bean).isAutoStartup())) {
            if (logger.isTraceEnabled()) {
                logger.trace("Starting bean '" + beanName + "' of type [" + bean.getClass().getName() + "]");
            }
            try {
                // 廬山真面目,最終調到了`Lifecycle`的`start`方法。
                bean.start();
            }
            catch (Throwable ex) {
                throw new ApplicationContextException("Failed to start bean '" + beanName + "'", ex);
            }
            if (logger.isDebugEnabled()) {
                logger.debug("Successfully started bean '" + beanName + "'");
            }
        }
    }
}

至此,onRefresh()方法分析完成。

destroyBeans方法

該方法用于銷毀bean,內部調用的是bean工廠的destroySingletons()方法?!咀⒁狻浚哼@兒僅銷毀了單例bean!

總結

我們從源碼層面分析了bean加載的整個過程,每個步驟各司其職,環(huán)環(huán)相扣,非常地精彩。其中最顯眼的地方在于Spring對bean循環(huán)依賴的解決方案(三級緩存)。

借鑒于網(wǎng)上的一張圖,bean加載的過程如下所示:

而這張圖標綠的地方,單獨解釋如下:

  • 獲取 BeanName,對傳入的 name 進行解析,轉化為可以從 Map 中獲取到BeanDefinition的 bean name。
  • 合并 Bean 定義,對父類的定義進行合并和覆蓋,如果父類還有父類,會進行遞歸合并,以獲取完整的Bean定義信息。
  • 實例化,使用構造或者工廠方法創(chuàng)建Bean實例。
    屬性填充,尋找并且注入依賴,依賴的Bean還會遞歸調用getBean方法獲取。
  • 初始化,調用自定義的初始化方法。
  • 獲取最終的 Bean,如果是FactoryBean需要調用getObject方法,如果需要類型轉換調用TypeConverter進行轉化。

除此之外,我們還需要關注一下bean的生命周期,這是貫穿Spring IOC的一條主線。

  1. 實例化bean
  2. 設置屬性值
  3. 調用BeanNameAware.setBeanName()方法
  4. 調用BeanFactoryAware.setBeanFactory()方法
  5. 調用BeanPostProcessor.postProcessBeforeInitialization()方法
    1. 調用ApplicationContextAware.setApplicationContext()方法
    2. 調用@PostConstruct所在的方法
    3. 其他...
  6. 調用InitializingBean.afterPropertiesSet()方法
  7. 調用init方法
  8. 調用BeanPostProcessor.postProcessAfterInitialization()方法
  9. 調用DisposableBean.destroy()方法
  10. 調用destory方法

參考文檔

  1. https://blog.csdn.net/nuomizhende45/article/details/81158383
  2. http://www.itdecent.cn/p/9ea61d204559
  3. https://www.cnblogs.com/lqmblog/p/8592817.html
  4. http://www.itdecent.cn/p/e4ca039a2272
  5. http://www.itdecent.cn/p/a6a03d94d6f7
  6. http://www.itdecent.cn/p/43b65ed2e166
  7. https://blog.csdn.net/f641385712/article/details/92801300
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容