(三)getBean的執行流程

Bean的生命週期

bean的生命週期比較複雜。簡化其生命週期後大體分爲java

  • 實例化。建立實例對象
  • 初始化。依賴注入,對bean執行初始化方法,執行後置處理器
  • 銷燬。銷燬bean

getBean的設計與實現

  • getBean()方法是BeanFactory對外暴露的方法。在須要使用bean時通常都會調用此方法獲取bean實例
  • AbstractBeanFactorygetBean()的全部重載方法都會調用doGetBean()方法
  • doGetBean()會先嚐試從容器中查找bean,若是找不到就調用createBean()doCreateBean()建立bean並將其添加到容器中
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
			@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
	
    // 若是name是&開頭的,方法的返回值會去掉name的&前綴。
    // FactoryBean的實現類的name會被加上'&'前綴
    final String beanName = transformedBeanName(name);
    Object bean;

    // 嘗試從容器中獲取單實例bean,若是獲取不到再嘗試建立bean
    Object sharedInstance = getSingleton(beanName);
    if (sharedInstance != null && args == null) {
        // 若是name以'&'開頭,方法返回值爲sharedInstance
        // 若是name不以'&'開頭,且sharedInstance時FactoryBean,方法返回值爲FactoryBean建立的對象
        // FactoryBean建立的對象會被緩存到 專門存放FactoryBean生成的對象的map中(FactoryBeanRegistrySupport-的成員變量 factoryBeanObjectCache)
        bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    }

    else {
        ...
        // 嘗試獲取父容器,若是有父容器,嘗試調用父容器的getBean方法獲取bean。在Spring MVC時再說這個父子容器/雙親容器
        BeanFactory parentBeanFactory = getParentBeanFactory();
        if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
            String nameToLookup = originalBeanName(name);
            if (parentBeanFactory instanceof AbstractBeanFactory) {
                return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
                    nameToLookup, requiredType, args, typeCheckOnly);
            }
            else if (args != null) {
                return (T) parentBeanFactory.getBean(nameToLookup, args);
            }
            else {
                return parentBeanFactory.getBean(nameToLookup, requiredType);
            }
        }
		...
        try {
            // 根據beanName,獲取BeanDefinition。以此爲模板建立bean實例
            final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
            checkMergedBeanDefinition(mbd, beanName, args);

            // 獲取此bean所依賴的其餘bean
            String[] dependsOn = mbd.getDependsOn();
            if (dependsOn != null) {
                for (String dep : dependsOn) {
                    if (isDependent(beanName, dep)) {
                        throw ...
                    }
                    registerDependentBean(dep, beanName);
                    try {
                        getBean(dep);
                    }
                    catch (NoSuchBeanDefinitionException ex) {
                        throw ...
                    }
                }
            }

            // 建立單實例bean的入口
            if (mbd.isSingleton()) {
                // 在方法中會調用lambda表達式實現的方法建立bean。下一段代碼分析將圍繞此方法
                sharedInstance = getSingleton(beanName, () -> {
                    try {
                        return createBean(beanName, mbd, args);
                    }
                    catch (BeansException ex) {
                        ...
                    }
                });
				// 若是bean是FactoryBean那麼方法返回值爲FactoryBean建立的對象,若是不是,返回值爲sharedInstance
                bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
            }
			// 建立多實例bean的入口
            else if (mbd.isPrototype()) {
                ...
            }
			// 建立其餘類型實例的入口
            else {
               ...
            }
        }
        catch (BeansException ex) {
            ...
        }
    }
	...
    return (T) bean;
}

getSingleton()方法作了哪些事?緩存

  • 調用singletonFactory.getObject()建立bean對象
  • 調用addSingleton()將bean添加到容器中
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
    synchronized (this.singletonObjects) {
        // 再次嘗試從容器中獲取bean,若是能獲取到就直接return
        Object singletonObject = this.singletonObjects.get(beanName);
        if (singletonObject == null) {
            beforeSingletonCreation(beanName);
            boolean newSingleton = false;
            boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
            if (recordSuppressedExceptions) {
                this.suppressedExceptions = new LinkedHashSet<>();
            }
            try {
                // 建立bean實例,此對象的方法實現由doGetBean中調用處使用lambda表達式實現。下面分析此方法的實現
                singletonObject = singletonFactory.getObject();
                newSingleton = true;
            }
            catch (Exception ex) {
                ...
            }
            finally {
               ...
            }
            if (newSingleton) {
                // 將建立好的bean添加到緩存中
                addSingleton(beanName, singletonObject);
            }
        }
        return singletonObject;
    }
}

createBean的設計與實現

  • createBean() 在執行一些準備工做後會調用doCreateBean()(建立bean的方法)
  • doCreateBean()建立bean的流程包含實例化bean,初始化bean
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
    RootBeanDefinition mbdToUse = mbd;
	...
    try {
        // 給它一個機會返回一個代理對象(通常返回值都是null),因此一般船艦bean實例的方法是doCreateBean
        // 此處用於執行容器中InstantiationAwareBeanPostProcessor類型的後置處理器的applyBeanPostProcessorsBefore/AfterInstantiation方法
        Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
        if (bean != null) {
            return bean;
        }
    }
    catch (Throwable ex) {
        throw ...
    }

    try {
        // 建立bean實例。下面分析這段代碼
        Object beanInstance = doCreateBean(beanName, mbdToUse, args);
        return beanInstance;
    }
    catch (Throwable ex) {
        throw ...
    }
}

doCreateBean()包含實例化bean,初始化beanapp

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
			throws BeanCreationException {
	// 建立的bean實例會暫時被包裝在此對象中
    BeanWrapper instanceWrapper = null;
    if (mbd.isSingleton()) {
        instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
    }
    if (instanceWrapper == null) {
        // 建立bean實例,並將bean包裝在BeanWrapper中
        instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
    // 從包裝類中取出bean
    final Object bean = instanceWrapper.getWrappedInstance();
    Class<?> beanType = instanceWrapper.getWrappedClass();
    if (beanType != NullBean.class) {
        mbd.resolvedTargetType = beanType;
    }

    synchronized (mbd.postProcessingLock) {
        if (!mbd.postProcessed) {
            try {
                // 遍歷容器中的MergedBeanDefinitionPostProcessor並調用postProcessMergedBeanDefinition
                applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
            }
            catch (Throwable ex) {
               ...
            }
            mbd.postProcessed = true;
        }
    }

    boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
                                      isSingletonCurrentlyInCreation(beanName));
    if (earlySingletonExposure) {
        ...
        addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
    }

    Object exposedObject = bean;
    try {
        // 依賴注入的入口
        // 除了依賴注入外,還會遍歷容器中的InstantiationAwareBeanPostProcessor調用postProcessPropertyValues
        populateBean(beanName, mbd, instanceWrapper);
        // 初始化bean
        exposedObject = initializeBean(beanName, exposedObject, mbd);
    }
    catch (Throwable ex) {
        ...
    }

	...

    return exposedObject;
}
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
    // 若是bean實現瞭如下任意接口,BeanFactoryAware,BeanClassLoaderAware,BeanNameAware。那麼執行接口方法
    if (System.getSecurityManager() != null) {
        AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
            invokeAwareMethods(beanName, bean);
            return null;
        }, getAccessControlContext());
    }
    else {
        invokeAwareMethods(beanName, bean);
    }

    Object wrappedBean = bean;
    // 遍歷容器的BeanPostProcessor執行postProcessBeforeInitialization方法
    // 其中包含執行@PostConstruct指定的初始化方法
    if (mbd == null || !mbd.isSynthetic()) {
        wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    }

    try {
        // 1. 若是bean實現了InitializingBean接口,調用其afterPropertiesSet方法
        // 2. 若是在@Bean註解上指定了初試化方法,調用初始化方法
        invokeInitMethods(beanName, wrappedBean, mbd);
    }
    catch (Throwable ex) {
        throw ...
    }
    // 遍歷容器的BeanPostProcessor執行postProcessAfterInitialization方法
    if (mbd == null || !mbd.isSynthetic()) {
        wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }

    return wrappedBean;
}
相關文章
相關標籤/搜索