天天看點

【IoC-3】Spring bean 的建立過程前言正文補充:bean 建立的完整過程小結

bean 的建立過程

  • 前言
  • 正文
  • 補充:bean 建立的完整過程
  • 小結

系列博文:

【IoC-0】SpringIoC引入

【IoC-1】IoC之控制反轉引入

【IoC-2】IoC之BeanDefinition掃描注冊

【IoC-3】Spring bean 的建立過程

【IoC-4】IoC之依賴注入原理

相關閱讀:

@Resource與@Autowired的差別

前言

Spring 提供了"控制反轉"的能力,也就是将 bean 的建立交由 Spring 去統一處理。

前文分析了要實作"控制反轉"的功能,Spring 需要解決的問題是:

  1. BeanDefinition 的掃描和注冊
  2. 根據 BeanDefinition 來建立 bean 的執行個體

可以說"BeanDefinition 的掃描和注冊"隻是前戲,bean 執行個體的建立才是主菜。

上一篇已經分析了 BeanDefinition 的掃描和注冊,這裡我們主要再分析一下 bean 執行個體的建立過程。

正文

一個普通的單例 bean,如果沒有特殊的指定 FactoryMethod 或者 constructor 的話,就會使用預設的構造函數來建立 bean 的執行個體。

那麼,我們可以為一個普通的單例 bean 添加一個預設的構造函數,然後在上面打上斷點,來觀察 bean 執行個體建立時的調用堆棧。

觀察調用堆棧,是閱讀源碼的一個小技巧。可以快速的觀察到程式從開始到斷點處經過了哪些處理過程。
【IoC-3】Spring bean 的建立過程前言正文補充:bean 建立的完整過程小結

從調用堆棧中,可以看到,bean 執行個體的建立是在執行

AbstractApplicationContext#finishBeanFactoryInitialization()

的時候,調用

AbstractBeanFactory#getBean()

觸發的。

最終會調用

AbstractAutowireCapableBeanFactory#createBeanInstance()

:

/**
 * 通過一定的執行個體化政策,為指定的 bean 建立一個新的執行個體。  
 * 執行個體化政策為:  FactoryMethod --> constructor autowiring(構造注入) --> simple instantiation(調用預設構造函數)
 * Create a new instance for the specified bean, using an appropriate instantiation strategy: factory method, constructor autowiring, or simple instantiation.
 */
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
    // Make sure bean class is actually resolved at this point.
    Class<?> beanClass = resolveBeanClass(mbd, beanName);

    if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
    }

    Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
    if (instanceSupplier != null) {
        return obtainFromSupplier(instanceSupplier, beanName);
    }

    // 1. 通過指定的 FactoryMethod 來建立 bean 的執行個體
    if (mbd.getFactoryMethodName() != null) {
        return instantiateUsingFactoryMethod(beanName, mbd, args);
    }

    // Shortcut when re-creating the same bean...
    boolean resolved = false;
    boolean autowireNecessary = false;
    if (args == null) {
        synchronized (mbd.constructorArgumentLock) {
            if (mbd.resolvedConstructorOrFactoryMethod != null) {
                resolved = true;
                autowireNecessary = mbd.constructorArgumentsResolved;
            }
        }
    }
    if (resolved) {
        if (autowireNecessary) {
            return autowireConstructor(beanName, mbd, null, null);
        } else {
            return instantiateBean(beanName, mbd);
        }
    }

    // 2. 構造注入
    // Candidate constructors for autowiring?
    Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
    if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
            mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
        return autowireConstructor(beanName, mbd, ctors, args);
    }

    // Preferred constructors for default construction?
    ctors = mbd.getPreferredConstructors();
    if (ctors != null) {
        return autowireConstructor(beanName, mbd, ctors, null);
    }

    // 3. 使用無參構造函數來建立 bean 的執行個體。(即預設的構造函數)
    // No special handling: simply use no-arg constructor.
    return instantiateBean(beanName, mbd);
}
           

補充:bean 建立的完整過程

createBeanInstance()

方法隻是将 bean 的執行個體建立出來了,它還不是一個完整的 bean,因為 bean 裡面依賴的屬性還沒有填充值。

AbstractAutowireCapableBeanFactory.doCreateBean()

的源碼可以看到 bean 完整的建立過程:

【IoC-3】Spring bean 的建立過程前言正文補充:bean 建立的完整過程小結

小結

bean 執行個體的建立是在執行

AbstractApplicationContext#finishBeanFactoryInitialization()

的時候,調用

AbstractBeanFactory#getBean()

觸發的。

最終是由

AbstractAutowireCapableBeanFactory#createBeanInstance()

方法來完成 bean 執行個體的建立的。

bean 執行個體的建立政策為(優先級級從前往後):

  1. 通過指定的 FactoryMethod 來建立
  2. 構造注入的方式(通過指定的構造函數)
  3. 通過預設的構造函數來建立

建立一個完整的 bean 分三個階段:

  1. AbstractAutowireCapableBeanFactory#createBeanInstance()

    建立 bean 的執行個體

  2. AbstractAutowireCapableBeanFactory#populateBean()

    填充 bean 的依賴

  3. AbstractAutowireCapableBeanFactory#initializeBean()

    初始化 bean。

    對 bean 的執行個體執行一些初始化方法:

    awareMethods --> BeanPostProcessor --> initMethod(InitializingBean#afterPropertiesSet、指定的 initMethod)

如果本文對你有所幫助,歡迎點贊收藏!