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);
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值