Spring源码阅读

Posted coshaho

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring源码阅读相关的知识,希望对你有一定的参考价值。

我们先看AbstractBeanFactory.getBean方法,这个方法通过bean名称类型等信息获取类实例,如果实例不存在则生产。

    //---------------------------------------------------------------------
    // Implementation of BeanFactory interface
    //---------------------------------------------------------------------

    @Override
    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
     * bean名称
     * @param requiredType the required type of the bean to retrieve
     * 期望返回的bean类型
     * @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
     * 返回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名称转换,包括别名转换和&前缀处理(&前缀用于工厂类)
        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.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 = getObjectForBeanInstance(sharedInstance, name, beanName, null);
        }

        else {
            // Fail if we‘re already creating this bean instance:
            // We‘re assumably within a circular reference.
            // 防止类环形依赖创建时出现死锁
            if (isPrototypeCurrentlyInCreation(beanName)) {
                throw new BeanCurrentlyInCreationException(beanName);
            }

            // Check if bean definition exists in this factory.
            // 检查父工厂是否存在这个类实例
            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 {
                    // No args -> delegate to standard getBean method.
                    return parentBeanFactory.getBean(nameToLookup, requiredType);
                }
            }

            // 实例创建前上锁
            if (!typeCheckOnly) {
                markBeanAsCreated(beanName);
            }

            try {
                // 获取bean配置,这里会把配置转化为RootBeanDefinition
                final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                // 检查配置是否为抽象类
                checkMergedBeanDefinition(mbd, beanName, args);

                // Guarantee initialization of beans that the current bean depends on.
                // 优先加载依赖类
                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);
                        getBean(dep);
                    }
                }

                // Create bean instance.
                // 创建单例
                if (mbd.isSingleton()) {
                    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;
                        }
                    });
                    // 1、 如果有其他类依赖此类,需要进行通知
                    // 2、 如果此类是工厂类,一般需要调用工厂方法返回类实例,而不是直接返回工厂类
                    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                }
                // 创建多实例
                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);
                }

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

关键代码getSingleton下一讲继续研究。

以上是关于Spring源码阅读的主要内容,如果未能解决你的问题,请参考以下文章

初识Spring源码 -- doResolveDependency | findAutowireCandidates | @Order@Priority调用排序 | @Autowired注入(代码片段

如何阅读Spring源码

Spring源码解析——如何阅读源码

Spring源码分析专题 —— 阅读指引

spring源码阅读笔记之HelloWorld和spring第一步ClassPathXMLApplicationContext

Spring源码阅读