Spring源码解析之八finishBeanFactoryInitialization办法即初始化单例bean

七千字长文粗浅解读,Spirng中是如何初始化单例bean的,和面试中最常问的Spring是如何解决循环依赖?

明天解读Spring外围办法refresh()中最最重要的一个办法finishBeanFactoryInitialization()办法,该办法负责初始化所有的单例bean。

finishBeanFactoryInitialization()办法位于refresh()中下标为8的地位。

到目前为止,应该说 BeanFactory 曾经创立实现,并且所有的实现了 BeanFactoryPostProcessor 接口的 Bean 都曾经初始化并且其中的 postProcessBeanFactory(factory) 办法曾经失去回调执行了。而且 Spring 曾经“手动”注册了一些非凡的 Bean,如 environmentsystemProperties 等。

剩下的就是初始化 singleton beans 了,大都数咱们的业务中都是单例bean,就像咱们写的@Controller、@Service的类(没有设置懒加载的)都是在这个中央初始化,以供咱们应用,如果没有设置懒加载,那么 Spring 会在接下来初始化所有的 singleton beans。

咱们先看一下refresh()的源码,大略看下finishBeanFactoryInitialization(beanFactory)所处的地位。

@Override    public void refresh() throws BeansException, IllegalStateException {        synchronized (this.startupShutdownMonitor) {            // Prepare this context for refreshing.            //1、刷新前的筹备            prepareRefresh();            // Tell the subclass to refresh the internal bean factory.            //2、将会初始化 BeanFactory、加载 Bean、注册 Bean            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();            // Prepare the bean factory for use in this context.            //3、设置 BeanFactory 的类加载器,增加几个 BeanPostProcessor,手动注册几个非凡的 bean            prepareBeanFactory(beanFactory);            try {                //4、模板办法                // Allows post-processing of the bean factory in context subclasses.                postProcessBeanFactory(beanFactory);                // Invoke factory processors registered as beans in the context.                //执行BeanFactory后置处理器                invokeBeanFactoryPostProcessors(beanFactory);                // 5、Register bean processors that intercept bean creation.                //注册bean后置处理器                registerBeanPostProcessors(beanFactory);                // Initialize message source for this context.                //国际化                initMessageSource();                // Initialize event multicaster for this context.                initApplicationEventMulticaster();                // Initialize other special beans in specific context subclasses.                //6、模板办法--springboot实现了这个办法                onRefresh();                // Check for listener beans and register them.                //7、注册监听器                registerListeners();                // Instantiate all remaining (non-lazy-init) singletons.                //8、实现bean工厂的初始化**办法重要**********************************************                finishBeanFactoryInitialization(beanFactory);                //9、 Last step: publish corresponding event.                finishRefresh();            }

咱们深刻finishBeanFactoryInitialization(beanFactory)中,外面的调用线路盘根错节,还望读者能够做好心理准备。

/**     * 负责单例bean的初始化     * Finish the initialization of this context's bean factory,     * initializing all remaining singleton beans.     */    protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {        // Initialize conversion service for this context.        //最先初始化名字为 conversionService的类,conversionService类 它用来将前端传过来的参数和后端的 controller 办法上的参数进行绑定的时候用        //尤其是用于非根底类型的转换        if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&                beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {            beanFactory.setConversionService(                    //初始化在getBean()办法中实现                    beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));        }        // Register a default embedded value resolver if no bean post-processor        // (such as a PropertyPlaceholderConfigurer bean) registered any before:        // at this point, primarily for resolution in annotation attribute values.        if (!beanFactory.hasEmbeddedValueResolver()) {            beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));        }        // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.        // 先初始化 LoadTimeWeaverAware 类型的 Bean aop相关注:大略有个印象,当前解析aop会和它串起来。        String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);        for (String weaverAwareName : weaverAwareNames) {            getBean(weaverAwareName);        }        // Stop using the temporary ClassLoader for type matching.        beanFactory.setTempClassLoader(null);        // Allow for caching all bean definition metadata, not expecting further changes.        //freeze的单词意思是解冻,这个时候曾经开始预初始化, bean 定义解析、加载、注册先进行        beanFactory.freezeConfiguration();        // Instantiate all remaining (non-lazy-init) singletons.        //开始初始化        beanFactory.preInstantiateSingletons();    }

该办法是判断bean的一系列是不是属于某个类型的bean,如果是就调用getBean()办法,如果不是,就调用beanFactory.preInstantiateSingletons()进行初始化,咱们先把getBean()放一放,重点看一看beanFactory.preInstantiateSingletons()办法。

@Override    public void preInstantiateSingletons() throws BeansException {        if (logger.isTraceEnabled()) {            logger.trace("Pre-instantiating singletons in " + this);        }        // Iterate over a copy to allow for init methods which in turn register new bean definitions.        // While this may not be part of the regular factory bootstrap, it does otherwise work fine.        // this.beanDefinitionNames 保留了所有的 beanNames        List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);        // Trigger initialization of all non-lazy singleton beans...        //// 上面这个循环,触发所有的非懒加载的 singleton beans 的初始化操作        for (String beanName : beanNames) {            RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);            // 非形象、非懒加载的 singletons。如果配置了 'abstract = true',那是不须要初始化的            if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {                // 解决 FactoryBean (负责初始化工厂的bean)                if (isFactoryBean(beanName)) {                    // FactoryBean 的话,在 beanName 后面加上 ‘&’ 符号                    //此处调用getBean()办法                    Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);                    if (bean instanceof FactoryBean) {                        FactoryBean<?> factory = (FactoryBean<?>) bean;                        // 判断以后 FactoryBean 是否是 SmartFactoryBean 的实现                        boolean isEagerInit;                        if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {                            isEagerInit = AccessController.doPrivileged(                                    (PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,                                    getAccessControlContext());                        }                        else {                            isEagerInit = (factory instanceof SmartFactoryBean &&                                    ((SmartFactoryBean<?>) factory).isEagerInit());                        }                        if (isEagerInit) {                            getBean(beanName);                        }                    }                }                else {                    // 对于一般的 Bean,只有调用 getBean(beanName) 这个办法就能够进行初始化了                    getBean(beanName);                }            }        }        // Trigger post-initialization callback for all applicable beans...        // 到这里阐明所有的非懒加载的 singleton beans 曾经实现了初始化        // 如果咱们定义的 bean 是实现了 SmartInitializingSingleton 接口的,那么在这里失去回调        //如果你想在单例bean初始化后做一些事 那就实现该接口        for (String beanName : beanNames) {            Object singletonInstance = getSingleton(beanName);            if (singletonInstance instanceof SmartInitializingSingleton) {                SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;                if (System.getSecurityManager() != null) {                    AccessController.doPrivileged((PrivilegedAction<Object>) () -> {                        smartSingleton.afterSingletonsInstantiated();                        return null;                    }, getAccessControlContext());                }                else {                    smartSingleton.afterSingletonsInstantiated();                }            }        }    }

preInstantiateSingletons()办法的次要工作是进行初始化的,在初始化前同样是一系列判断,如,是否是懒加载的,是否是一个factorybean(一个特地的bean,负责工厂创立的bean),最初调用getBean()办法。

其中有个插曲是否实现了SmartInitializingSingleton接口,将接口让你能够在bean初始化后做一些事,咱们写一个简略的实例测试一下。

其余中央读者看正文理解一下即可,咱们开始持续深刻getBean()办法。

getBean()办法外部调用了doGetBean()咱们间接看doGetBean办法。

        // 咱们在分析初始化 Bean 的过程,然而 getBean 办法咱们常常是用来从容器中获取 Bean 用的,留神切换思路,    // 曾经初始化过了就从容器中间接返回,否则就先初始化再返回    protected <T> T doGetBean(            String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)            throws BeansException {        // 获取一个 “正统的” beanName,解决两种状况,一个是后面说的 FactoryBean(后面带 ‘&’),        // 一个是别名问题,因为这个办法是 getBean,获取 Bean 用的,你要是传一个别名进来,是齐全能够的        String beanName = transformedBeanName(name);        // 返回值        Object bean;        // Eagerly check singleton cache for manually registered singletons.        // 查看下是不是曾经创立过了        Object sharedInstance = getSingleton(beanName);        // 这里说下 args ,尽管看上去一点不重要。后面咱们一路进来的时候都是 getBean(beanName),        // 所以 args 传参其实是 null 的,然而如果 args 不为空的时候,那么意味着调用方不是心愿获取 Bean,而是创立 Bean        if (sharedInstance != null && args == null) {            if (logger.isTraceEnabled()) {                if (isSingletonCurrentlyInCreation(beanName)) {                    logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +                            "' that is not fully initialized yet - a consequence of a circular reference");                }                else {                    logger.trace("Returning cached instance of singleton bean '" + beanName + "'");                }            }            // 上面这个办法:如果是一般 Bean 的话,间接返回 sharedInstance,            // 如果是 FactoryBean 的话,返回它创立的那个实例对象            bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);        }        else {            // Fail if we're already creating this bean instance:            // We're assumably within a circular reference.            // 创立过了此 beanName 的 prototype 类型的 bean,那么抛异样,            // 往往是因为陷入了循环援用 哦,原来之前的循环依赖都是在这抛的异样,再有问题就不是无头苍蝇了            if (isPrototypeCurrentlyInCreation(beanName)) {                throw new BeanCurrentlyInCreationException(beanName);            }            // Check if bean definition exists in this factory.            // 检查一下这个 BeanDefinition 在容器中是否存在 BeanDefinition既是蕴含了bean的一系列信息            BeanFactory parentBeanFactory = getParentBeanFactory();            if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {                // Not found -> check parent.                // 如果以后容器不存在这个 BeanDefinition,试试父容器中有没有                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 if (requiredType != null) {                    // No args -> delegate to standard getBean method.                    return parentBeanFactory.getBean(nameToLookup, requiredType);                }                else {                    return (T) parentBeanFactory.getBean(nameToLookup);                }            }            if (!typeCheckOnly) {                // typeCheckOnly 为 false,将以后 beanName 放入一个 alreadyCreated 的 Set 汇合中。                markBeanAsCreated(beanName);            }            /*             * 稍稍总结一下:             * 到这里的话,要筹备创立 Bean 了,对于 singleton 的 Bean 来说,容器中还没创立过此 Bean;             * 对于 prototype 的 Bean 来说,原本就是要创立一个新的 Bean。             */            try {                RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);                checkMergedBeanDefinition(mbd, beanName, args);                // Guarantee initialization of beans that the current bean depends on.                // 先初始化依赖的所有 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);                        try {                            // 先初始化被依赖项                            getBean(dep);                        }                        catch (NoSuchBeanDefinitionException ex) {                            throw new BeanCreationException(mbd.getResourceDescription(), beanName,                                    "'" + beanName + "' depends on missing bean '" + dep + "'", ex);                        }                    }                }                // Create bean instance.                // 如果是 singleton scope 的,创立 singleton 的实例                if (mbd.isSingleton()) {                    sharedInstance = getSingleton(beanName, () -> {                        try {                            // 执行创立 Bean,详情持续深刻                            // 第三个参数 args 数组代表创立实例须要的参数,不就是给构造方法用的参数,或者是工厂 Bean 的参数嘛,不过要留神,在咱们的初始化阶段,args 是 null。                            // 这回咱们要到一个新的类了 AbstractAutowireCapableBeanFactory,看类名,AutowireCapable?类名是不是也阐明了点问题了。                            // 次要是为了以下场景,采纳 @Autowired 注解注入属性值:                            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;                        }                    });                    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);                }                // 如果是 prototype scope 的,创立 prototype 的实例                else if (mbd.isPrototype()) {                    // It's a prototype -> create a new instance.                    Object prototypeInstance = null;                    try {                        beforePrototypeCreation(beanName);                        // 执行创立 Bean                        prototypeInstance = createBean(beanName, mbd, args);                    }                    finally {                        afterPrototypeCreation(beanName);                    }                    bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);                }                else {                    String scopeName = mbd.getScope();                    if (!StringUtils.hasLength(scopeName)) {                        throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");                    }                    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.isTraceEnabled()) {                    logger.trace("Failed to convert bean '" + name + "' to required type '" +                            ClassUtils.getQualifiedName(requiredType) + "'", ex);                }                throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());            }        }        return (T) bean;    }

具体的实例化过程在createBean()办法中,咱们持续深刻createBean()办法。

@Override    protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)            throws BeanCreationException {        if (logger.isTraceEnabled()) {            logger.trace("Creating instance of bean '" + beanName + "'");        }        RootBeanDefinition mbdToUse = mbd;        // Make sure bean class is actually resolved at this point, and        // clone the bean definition in case of a dynamically resolved Class        // which cannot be stored in the shared merged bean definition.        // 确保 BeanDefinition 中的 Class 被加载        Class<?> resolvedClass = resolveBeanClass(mbd, beanName);        if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {            mbdToUse = new RootBeanDefinition(mbd);            mbdToUse.setBeanClass(resolvedClass);        }        // Prepare method overrides.        // 筹备办法覆写,这里又波及到一个概念:MethodOverrides,它来自于 bean 定义中的 <lookup-method />        // 和 <replaced-method />,如果读者感兴趣,回到 bean 解析的中央看看对这两个标签的解析。        try {            mbdToUse.prepareMethodOverrides();        }        catch (BeanDefinitionValidationException ex) {            throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),                    beanName, "Validation of method overrides failed", ex);        }        try {            // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.            // 让 InstantiationAwareBeanPostProcessor 在这一步有机会返回代理,            // 在 《Spring AOP 源码剖析》那篇文章中有解释,这里先跳过            Object bean = resolveBeforeInstantiation(beanName, mbdToUse);            if (bean != null) {                return bean;            }        }        catch (Throwable ex) {            throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,                    "BeanPostProcessor before instantiation of bean failed", ex);        }        try {            // 重头戏,创立 bean            Object beanInstance = doCreateBean(beanName, mbdToUse, args);            if (logger.isTraceEnabled()) {                logger.trace("Finished creating instance of bean '" + beanName + "'");            }            return beanInstance;        }        catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {            // A previously detected exception with proper bean creation context already,            // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.            throw ex;        }        catch (Throwable ex) {            throw new BeanCreationException(                    mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);        }    }

咱们持续往里看 doCreateBean 这个办法,这个调用过程是真的深。

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)            throws BeanCreationException {        // Instantiate the bean.        BeanWrapper instanceWrapper = null;        if (mbd.isSingleton()) {            instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);        }        if (instanceWrapper == null) {            // 阐明不是 FactoryBean,这里实例化 Bean,这里十分要害,细节之后再说**********            instanceWrapper = createBeanInstance(beanName, mbd, args);        }        Object bean = instanceWrapper.getWrappedInstance();        Class<?> beanType = instanceWrapper.getWrappedClass();        if (beanType != NullBean.class) {            mbd.resolvedTargetType = beanType;        }        // Allow post-processors to modify the merged bean definition.        synchronized (mbd.postProcessingLock) {            if (!mbd.postProcessed) {                try {                    applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);                }                catch (Throwable ex) {                    throw new BeanCreationException(mbd.getResourceDescription(), beanName,                            "Post-processing of merged bean definition failed", ex);                }                mbd.postProcessed = true;            }        }        // Eagerly cache singletons to be able to resolve circular references        // even when triggered by lifecycle interfaces like BeanFactoryAware.        // 上面这块代码是为了解决循环依赖的问题,这是个重头戏,解决循环依赖问题        boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&                isSingletonCurrentlyInCreation(beanName));        if (earlySingletonExposure) {            if (logger.isTraceEnabled()) {                logger.trace("Eagerly caching bean '" + beanName +                        "' to allow for resolving potential circular references");            }            addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));        }        // Initialize the bean instance.        Object exposedObject = bean;        try {            // 这一步也是十分要害的,这一步负责属性拆卸,因为后面的实例只是实例化了,并没有设值,这里就是设值***************            populateBean(beanName, mbd, instanceWrapper);            // 还记得 init-method 吗?还有 InitializingBean 接口?还有 BeanPostProcessor 接口?            // 这里就是解决 bean 初始化实现后的各种回调**************            exposedObject = initializeBean(beanName, exposedObject, mbd);        }        catch (Throwable ex) {            if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {                throw (BeanCreationException) ex;            }            else {                throw new BeanCreationException(                        mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);            }        }    // 上面这块代码是为了解决循环依赖的问题,这是个重头戏,解决循环依赖问题            if (earlySingletonExposure) {                //循环依赖的外围办法调用            Object earlySingletonReference = getSingleton(beanName, false);            if (earlySingletonReference != null) {                if (exposedObject == bean) {                    exposedObject = earlySingletonReference;                }                else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {                    String[] dependentBeans = getDependentBeans(beanName);                    Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);                    for (String dependentBean : dependentBeans) {                        if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {                            actualDependentBeans.add(dependentBean);                        }                    }                    if (!actualDependentBeans.isEmpty()) {                        throw new BeanCurrentlyInCreationException(beanName,                                "Bean with name '" + beanName + "' has been injected into other beans [" +                                StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +                                "] in its raw version as part of a circular reference, but has eventually been " +                                "wrapped. This means that said other beans do not use the final version of the " +                                "bean. This is often the result of over-eager type matching - consider using " +                                "'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");                    }                }            }        }        // Register bean as disposable.        try {            registerDisposableBeanIfNecessary(beanName, bean, mbd);        }        catch (BeanDefinitionValidationException ex) {            throw new BeanCreationException(                    mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);        }        return exposedObject;    }

到这里,咱们曾经剖析完了 doCreateBean 办法,总的来说,咱们曾经说完了整个初始化流程。

在实例化bean后有一个特地重要的知识点,也是面试中最常问的,Spring怎么解决循环依赖问题?外围代码就在这个办法外面。

循环依赖其实就是循环援用,也就是两个或则两个以上的bean相互持有对方,最终造成闭环。比方A依赖于B,B依赖于C,C又依赖于A。如下图:

doCreateBean 办法有三个外围流程。

(1)createBeanInstance:实例化,其实也就是调用对象的构造方法实例化对象

(2)populateBean:填充属性,这一步次要是多bean的依赖属性进行填充

(3)initializeBean:调用spring xml中的init 办法。

从下面讲述的单例bean初始化步骤咱们能够晓得,循环依赖次要产生在第一、第二步。也就是结构器循环依赖和field循环依赖。

那么咱们要解决循环援用也应该从初始化过程着手,对于单例来说,在Spring容器整个生命周期内,有且只有一个对象,所以很容易想到这个对象应该存在Cache中,Spring为了解决单例的循环依赖问题,应用了三级缓存。

咱们看一下getSingleton办法。

该办法还依赖于三个map,这三个map就是三级缓存。

/** Cache of singleton objects: bean name to bean instance. *///单例对象的cacheprivate final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);/** Cache of singleton factories: bean name to ObjectFactory. */// 单例对象工厂的cacheprivate final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);/** Cache of early singleton objects: bean name to bean instance. *///提前曝光的单例对象的Cacheprivate final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);
@Nullable    protected Object getSingleton(String beanName, boolean allowEarlyReference) {        // Quick check for existing instance without full singleton lock        Object singletonObject = this.singletonObjects.get(beanName);                //判断以后单例bean是否正在创立中,也就是没有初始化实现(比方A的结构器依赖了B对象所以得先去创立B对象        // 或则在A的populateBean过程中依赖了B对象,得先去创立B对象,这时的A就是处于创立中的状态。        if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {            singletonObject = this.earlySingletonObjects.get(beanName);                        // 是否容许从singletonFactories中通过getObject拿到对象            if (singletonObject == null && allowEarlyReference) {                synchronized (this.singletonObjects) {                    // Consistent creation of early reference within full singleton lock                    singletonObject = this.singletonObjects.get(beanName);                    if (singletonObject == null) {                        singletonObject = this.earlySingletonObjects.get(beanName);                        if (singletonObject == null) {                            ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);                            if (singletonFactory != null) {                                singletonObject = singletonFactory.getObject();                                this.earlySingletonObjects.put(beanName, singletonObject);                                this.singletonFactories.remove(beanName);                            }                        }                    }                }            }        }        return singletonObject;    }

剖析getSingleton()的整个过程,Spring首先从一级缓存singletonObjects中获取。如果获取不到,并且对象正在创立中,就再从二级缓存earlySingletonObjects中获取。

如果还是获取不到且容许singletonFactories通过getObject()获取,就从三级缓存singletonFactory.getObject()(三级缓存)获取,如果获取到了则:

this.earlySingletonObjects.put(beanName, singletonObject);                        this.singletonFactories.remove(beanName);                        

从singletonFactories中移除,并放入earlySingletonObjects中。其实也就是从三级缓存挪动到了二级缓存。

从下面三级缓存的剖析,咱们能够晓得,Spring解决循环依赖的窍门就在于singletonFactories这个三级cache。

里就是解决循环依赖的要害,这段代码产生在createBeanInstance之后,也就是说单例对象此时曾经被创立进去(调用了结构器)。这个对象曾经被生产进去了,尽管还不完满(还没有进行初始化的第二步和第三步),然而曾经能被人认出来了(依据对象援用能定位到堆中的对象),所以Spring此时将这个对象提前曝光进去让大家意识,让大家应用。

这样做有什么益处呢?

让咱们来剖析一下“A的某个field或者setter依赖了B的实例对象,同时B的某个field或者setter依赖了A的实例对象”这种循环依赖的状况。

A首先实现了初始化的第一步,并且将本人提前曝光到singletonFactories中,此时进行初始化的第二步,发现自己依赖对象B,此时就尝试去get(B),发现B还没有被create,所以走create流程,B在初始化第一步的时候发现自己依赖了对象A,于是尝试get(A),尝试一级缓存singletonObjects(必定没有,因为A还没初始化齐全),尝试二级缓存earlySingletonObjects(也没有),尝试三级缓存singletonFactories,因为A通过ObjectFactory将本人提前曝光了,所以B可能通过ObjectFactory.getObject拿到A对象(尽管A还没有初始化齐全,然而总比没有好呀),B拿到A对象后顺利完成了初始化阶段1、2、3,齐全初始化之后将本人放入到一级缓存singletonObjects中。

此时返回A中,A此时能拿到B的对象顺利完成本人的初始化阶段2、3,最终A也实现了初始化,进去了一级缓存singletonObjects中,而且更加侥幸的是,因为B拿到了A的对象援用,所以B当初hold住的A对象实现了初始化。

晓得了这个原理时候,必定就晓得为啥Spring不能解决“A的构造方法中依赖了B的实例对象,同时B的构造方法中依赖了A的实例对象”这类问题了!因为退出singletonFactories三级缓存的前提是执行了结构器,所以结构器的循环依赖没法解决。

接下来咱们挑 doCreateBean 中的三个细节进去说说。一个是创立 Bean 实例的 createBeanInstance 办法,一个是依赖注入的 populateBean 办法,还有就是回调办法 initializeBean。

这三个办法也是极其简单的,读者有趣味能够持续的深刻进去。

1、 createBeanInstance 办法

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {        // Make sure bean class is actually resolved at this point.        // 确保曾经加载了此 class        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);        }        if (mbd.getFactoryMethodName() != null) {            // 采纳工厂办法实例化,不相熟这个概念的读者请看附录,留神,不是 FactoryBean            return instantiateUsingFactoryMethod(beanName, mbd, args);        }        // Shortcut when re-creating the same bean...        // 如果不是第一次创立,比方第二次创立 prototype 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);            }        }        // 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);        }        // No special handling: simply use no-arg constructor.        // 调用无参构造函数        return instantiateBean(beanName, mbd);    }

看一下instantiateBean办法是怎么做的。

protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {        try {            Object beanInstance;            if (System.getSecurityManager() != null) {                beanInstance = AccessController.doPrivileged(                        (PrivilegedAction<Object>) () -> getInstantiationStrategy().instantiate(mbd, beanName, this),                        getAccessControlContext());            }            else {                // 实例化                beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);            }            // 包装一下,返回            BeanWrapper bw = new BeanWrapperImpl(beanInstance);            initBeanWrapper(bw);            return bw;        }        catch (Throwable ex) {            throw new BeanCreationException(                    mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);        }    }

咱们能够看到,要害的中央在于:beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);

外面是具体是实例化过程,咱们进去看看。

@Override    public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {        // Don't override the class with CGLIB if no overrides.        // 如果不存在办法覆写,那就应用 java 反射进行实例化,否则应用 CGLIB,        // 办法覆写 请参见附录"办法注入"中对 lookup-method 和 replaced-method 的介绍        if (!bd.hasMethodOverrides()) {            Constructor<?> constructorToUse;            synchronized (bd.constructorArgumentLock) {                constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;                if (constructorToUse == null) {                    final Class<?> clazz = bd.getBeanClass();                    if (clazz.isInterface()) {                        throw new BeanInstantiationException(clazz, "Specified class is an interface");                    }                    try {                        if (System.getSecurityManager() != null) {                            constructorToUse = AccessController.doPrivileged(                                    (PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);                        }                        else {                            constructorToUse = clazz.getDeclaredConstructor();                        }                        bd.resolvedConstructorOrFactoryMethod = constructorToUse;                    }                    catch (Throwable ex) {                        throw new BeanInstantiationException(clazz, "No default constructor found", ex);                    }                }            }            // 利用构造方法进行实例化            return BeanUtils.instantiateClass(constructorToUse);        }        else {            // Must generate CGLIB subclass.            // 存在办法覆写,利用 CGLIB 来实现实例化,须要依赖于 CGLIB 生成子类,这里就不开展了。            // tips: 因为如果不应用 CGLIB 的话,存在 override 的状况 JDK 并没有提供相应的实例化反对            return instantiateWithMethodInjection(bd, beanName, owner);        }    }

到这里,咱们就算实例化实现了。咱们开始说怎么进行属性注入。

2、populateBean 办法

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {        if (bw == null) {            if (mbd.hasPropertyValues()) {                throw new BeanCreationException(                        mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");            }            else {                // Skip property population phase for null instance.                return;            }        }        // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the        // state of the bean before properties are set. This can be used, for example,        // to support styles of field injection.        if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {            for (BeanPostProcessor bp : getBeanPostProcessors()) {                if (bp instanceof InstantiationAwareBeanPostProcessor) {                    InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;                    if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {                        return;                    }                }            }        }        // bean 实例的所有属性都在这里了        PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);        int resolvedAutowireMode = mbd.getResolvedAutowireMode();        // 通过名字找到所有属性值,如果是 bean 依赖,先初始化依赖的 bean。记录依赖关系        if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {            MutablePropertyValues newPvs = new MutablePropertyValues(pvs);            // Add property values based on autowire by name if applicable.            if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {                autowireByName(beanName, mbd, bw, newPvs);            }            // Add property values based on autowire by type if applicable.            if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {                autowireByType(beanName, mbd, bw, newPvs);            }            pvs = newPvs;        }        boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();        boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);        PropertyDescriptor[] filteredPds = null;        if (hasInstAwareBpps) {            if (pvs == null) {                pvs = mbd.getPropertyValues();            }            for (BeanPostProcessor bp : getBeanPostProcessors()) {                if (bp instanceof InstantiationAwareBeanPostProcessor) {                    InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;                    PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);                    if (pvsToUse == null) {                        if (filteredPds == null) {                            filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);                        }                        // 这里有个十分有用的 BeanPostProcessor 进到这里: AutowiredAnnotationBeanPostProcessor                        // 对采纳 @Autowired、@Value 注解的依赖进行设值,这里的内容也是十分丰盛的                        pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);                        if (pvsToUse == null) {                            return;                        }                    }                    pvs = pvsToUse;                }            }        }        if (needsDepCheck) {            if (filteredPds == null) {                filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);            }            checkDependencies(beanName, mbd, filteredPds, pvs);        }        if (pvs != null) {            // 设置 bean 实例的属性值            applyPropertyValues(beanName, mbd, bw, pvs);        }    }

属性注入实现后,这一步其实就是解决各种回调了,这块代码比较简单。

3、 initializeBean办法

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {        if (System.getSecurityManager() != null) {            AccessController.doPrivileged((PrivilegedAction<Object>) () -> {                invokeAwareMethods(beanName, bean);                return null;            }, getAccessControlContext());        }        else {            // 如果 bean 实现了 BeanNameAware、BeanClassLoaderAware 或 BeanFactoryAware 接口,回调            invokeAwareMethods(beanName, bean);        }        Object wrappedBean = bean;        if (mbd == null || !mbd.isSynthetic()) {            // BeanPostProcessor 的 postProcessBeforeInitialization 回调            wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);        }        try {            // 解决 bean 中定义的 init-method,            // 或者如果 bean 实现了 InitializingBean 接口,调用 afterPropertiesSet() 办法            invokeInitMethods(beanName, wrappedBean, mbd);        }        catch (Throwable ex) {            throw new BeanCreationException(                    (mbd != null ? mbd.getResourceDescription() : null),                    beanName, "Invocation of init method failed", ex);        }        if (mbd == null || !mbd.isSynthetic()) {            // BeanPostProcessor 的 postProcessAfterInitialization 回调            //BeanPostProcessor 的两个回调都产生在这边,只不过两头解决了 init-method            wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);        }        return wrappedBean;    }

自此,Spring实例化单例非懒加载bean的过程也就实现了,这也是Spirng最最重要的办法了。在咱们的日常应用Spring中,定义好各个类,而后在下面加上,@Controller,@Service,Autowired等注解,这些注解是怎么起作用的呢?

想必大部分同学都是知其然,不知其所以然,想必通过本文,读者心中能有一个分明的意识。