Spring源碼分析之——getBean細節

先看一下調用圖,方便後面看代碼 

@Test
public void testGetBean() {
    // 業務代碼
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-bean.xml");

    XXXX xxxx = applicationContext.getBean(XXXX.class);
}

 

org.springframework.context.support.AbstractApplicationContext 

public <T> T getBean(Class<T> requiredType) throws BeansException {
    assertBeanFactoryActive();
    return getBeanFactory().getBean(requiredType);
}

 

org.springframework.beans.factory.support.DefaultListableBeanFactory

@Override
public <T> T getBean(Class<T> requiredType) throws BeansException {
    return getBean(requiredType, (Object[]) null);
}

@Override
public <T> T getBean(Class<T> requiredType, Object... args) throws BeansException {
    // 在這一步就把bean獲取到了,bean是封裝在namedBean中
    NamedBeanHolder<T> namedBean = resolveNamedBean(requiredType, args);
    if (namedBean != null) {
        return namedBean.getBeanInstance();
    }
    // 如果當前BeanFactory獲取不到,則到父BeanFactory獲取
    BeanFactory parent = getParentBeanFactory();
    if (parent != null) {
        return parent.getBean(requiredType, args);
    }
    throw new NoSuchBeanDefinitionException(requiredType);
}

private <T> NamedBeanHolder<T> resolveNamedBean(Class<T> requiredType, Object... args) throws BeansException {
    Assert.notNull(requiredType, "Required type must not be null");

    // 從名稱映射緩存Map中取請求名稱數組
    String[] candidateNames = getBeanNamesForType(requiredType);

    if (candidateNames.length > 1) {
        List<String> autowireCandidates = new ArrayList<String>(candidateNames.length);
        for (String beanName : candidateNames) {
            // isAutowireCandidate該bean是否有資格自動注入
            if (!containsBeanDefinition(beanName) || getBeanDefinition(beanName).isAutowireCandidate()) {
                autowireCandidates.add(beanName);
            }
        }
        if (!autowireCandidates.isEmpty()) {
            candidateNames = StringUtils.toStringArray(autowireCandidates);
        }
    }

    if (candidateNames.length == 1) {
        String beanName = candidateNames[0];
        // 正常情況,通過getBean獲取Bean,有點隱蔽★★★★★
        // 需要注意的是bean要封裝成NamedBeanHolder的形式返回★★★★★
        return new NamedBeanHolder<T>(beanName, getBean(beanName, requiredType, args));
    }
    else if (candidateNames.length > 1) {
        // 如果有多個的話,根據bean的配置是否有@Primary註解來確定查哪個bean
        // 加入都有@Primary註解就報錯,邏輯在方法:determinePrimaryCandidate
        Map<String, Object> candidates = new LinkedHashMap<String, Object>(candidateNames.length);
        for (String beanName : candidateNames) {
            if (containsSingleton(beanName)) {
                candidates.put(beanName, getBean(beanName, requiredType, args));
            }
            else {
                candidates.put(beanName, getType(beanName));
            }
        }
        // 決定到底查哪個bean,看bena的@Primary註解
        String candidateName = determinePrimaryCandidate(candidates, requiredType);
        if (candidateName == null) {
            candidateName = determineHighestPriorityCandidate(candidates, requiredType);
        }
        if (candidateName != null) {
            Object beanInstance = candidates.get(candidateName);
            if (beanInstance instanceof Class) {
                beanInstance = getBean(candidateName, requiredType, args);
            }
            return new NamedBeanHolder<T>(candidateName, (T) beanInstance);
        }
        throw new NoUniqueBeanDefinitionException(requiredType, candidates.keySet());
    }

    return null;
}

 

org.springframework.beans.factory.support.AbstractBeanFactory

public <T> T getBean(String name, Class<T> requiredType, Object... args) throws BeansException {
    // 調用後續方法
    return doGetBean(name, requiredType, args, false);
}

protected <T> T doGetBean(
        final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
        throws BeansException {

    // 首先對bean name做轉換,因爲有可能傳的是別名
    final String beanName = transformedBeanName(name);
    // 定義待返回的bean引用
    Object bean; 

    // Eagerly check singleton cache for manually registered singletons.
    // 核心代碼:獲取單例bean
    Object sharedInstance = getSingleton(beanName);
    if (sharedInstance != null && args == null) {
        if (logger.isDebugEnabled()) {
            if (isSingletonCurrentlyInCreation(beanName)) {
                logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
                        "' that is not fully initialized yet - a consequence of a circular reference");
            }
            else {
                logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
            }
        }
        // 這裏涉及父子bean的屬性合併等,可以過
        bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    }
    else {
        // 代碼省略。。。
    }

    // Check if required type matches the type of the actual bean instance.
    if (requiredType != null && bean != null && !requiredType.isInstance(bean)) {
        try {
            return getTypeConverter().convertIfNecessary(bean, requiredType);
        }
        catch (TypeMismatchException ex) {
            if (logger.isDebugEnabled()) {
                logger.debug("Failed to convert bean '" + name + "' to required type '" +
                        ClassUtils.getQualifiedName(requiredType) + "'", ex);
            }
            throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
        }
    }
    return (T) bean;
}

 

org.springframework.beans.factory.support.DefaultSingletonBeanRegistry

@Override
public Object getSingleton(String beanName) {
    return getSingleton(beanName, true);
}

protected Object getSingleton(String beanName, boolean allowEarlyReference) {
    // 從這裏可以看到spring初始化完成以後單例bean的存儲位置:singletonObjects
    Object singletonObject = this.singletonObjects.get(beanName);

    // 如果singletonObjects中沒有&&當前bean正在創建,進入二三緩存中取
    // spring在裝配bean的時候設置了三級緩存,分別是:
    // 一級緩存:singletonObjects
    // 二級緩存:earlySingletonObjects
    // 三級緩存:singletonFactories
    if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
        synchronized (this.singletonObjects) {
            singletonObject = this.earlySingletonObjects.get(beanName);
            if (singletonObject == null && allowEarlyReference) {
                ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                if (singletonFactory != null) {
                    singletonObject = singletonFactory.getObject();
                    this.earlySingletonObjects.put(beanName, singletonObject);
                    this.singletonFactories.remove(beanName);
                }
            }
        }
    }
    return (singletonObject != NULL_OBJECT ? singletonObject : null);
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章