注释部分为spring循环依赖的解释,由于方便调阅源码使用了很对{@link},所以讲这文件放在spring源码中阅读会比较方便

本文详细解析了Spring框架中处理循环依赖的过程,从`DefaultSingletonBeanRegistry`的`getSingleton`方法出发,深入探讨了单例缓存、对象工厂以及在创建Bean时如何检测和处理循环依赖。通过分析`doCreateBean`方法,阐述了包括构造器注入、属性注入等步骤,并揭示了在循环依赖场景下如何选择合适的依赖候选者。
摘要由CSDN通过智能技术生成

/*

  • Copyright 2002-2019 the original author or authors.
  • Licensed under the Apache License, Version 2.0 (the “License”);
  • you may not use this file except in compliance with the License.
  • You may obtain a copy of the License at
  •  https://www.apache.org/licenses/LICENSE-2.0
    
  • Unless required by applicable law or agreed to in writing, software
  • distributed under the License is distributed on an “AS IS” BASIS,
  • WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  • See the License for the specific language governing permissions and
  • limitations under the License.
    */

/**
* 执行到当前这个doGetBean(final String name, @Nullable final Class requiredType,
@Nullable final Object[] args, boolean typeCheckOnly)
方法时会先去调用一下{@link DefaultSingletonBeanRegistry#getSingleton(String)},验证一下该Bean是否有被缓存过,缓存有三种第一次创建Bean是肯定都为空
* 1.{@link singletonObjects} 创建完成的Bean单例缓存池
* 2.{@link earlySingletonObjects}译文:早期的单例对象,可以理解为创建中的Bean单例池
* 3.{@link singletonFactories}单例工厂缓存池
* 然后会执行到{@link DefaultSingletonBeanRegistry#getSingleton(String, ObjectFactory)}这个重载方法,其中ObjectFactory参数是个对象工厂,由lambd表达式来获取的,这个方法
* 会调用到{@link DefaultSingletonBeanRegistry#beforeSingletonCreation}方法将当前Bena (以下称为Bean A) 的Name暂时缓存到{@link DefaultSingletonBeanRegistry#singletonsCurrentlyInCreation}
* 在这个方法往下8行的singletonObject = singletonFactory.getObject();中调用lambd表达式创建对象并返回ObjectFactory,
* 在lambd表达式中调用了{@link AbstractAutowireCapableBeanFactory#createBean -> Object beanInstance = doCreateBean(beanName, mbdToUse, args);}
* ----------------------------------------------------------------------------分割线------------------------------------------------------------------
* createBean:
* 一个普通Bean的创建要经过,
* 构造方法推断{@link AbstractAutowireCapableBeanFactory#createBeanInstance->
* @link AbstractAutowireCapableBeanFactory#determineConstructorsFromBeanPostProcessors
* 实例化 推断的有参构造{@link AbstractAutowireCapableBeanFactory#autowireConstructor}方法去实例化,无参{@link AbstractAutowireCapableBeanFactory#instantiateBean}、
* ----------------------------------------------------这里实例化了一个对象然后包装成BeanWrapper--------------------------------------------------
* 注入的元数据类型合并{@link MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition(RootBeanDefinition, Class, String)}->
* @Autowire {@link AutowiredAnnotationBeanPostProcessor},
* @Resource {@link org.springframework.context.annotation.CommonAnnotationBeanPostProcessor}
* 循环依赖判断{@link AbstractAutowireCapableBeanFactory#doCreateBean#earlySingletonExposure},
* 为true->循环依赖缓存 {@link AbstractAutowireCapableBeanFactory#addSingletonFactory }方法将objectFactories放入{@link singletonFactories}缓存
* 属性注入{@link AbstractAutowireCapableBeanFactory#populateBean}
* {@link InstantiationAwareBeanPostProcessor#postProcessProperties 3中解析,最常用的一下两种}->
* @Autowire : {@link AutowiredAnnotationBeanPostProcessor#postProcessProperties(PropertyValues, Object, String)},
* @Resource : {@link org.springframework.context.annotation.CommonAnnotationBeanPostProcessor#postProcessProperties}
* ->{@link InjectionMetadata#inject(Object, String, PropertyValues) 这个方法在上面的BeanPostProcessor中都调用了,用于属性注入}
* ->{@link AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement#inject(Object, String, PropertyValues) ({@link InjectionMetadata.InjectedElement}的子类)
* 这里先得到需要装配的属性利用反射赋值给Field }
* ->{@link DefaultListableBeanFactory#resolveDependency(DependencyDescriptor, String, Set, TypeConverter)}
* ->{@link DefaultListableBeanFactory#doResolveDependency(DependencyDescriptor, String, Set, TypeConverter)
* bytype–isAutowiredcandidate—generictype—qualifier—Map–primary --priority —
* @Value—>如果没有@Value,根据type查找—>isAutowireCandidate----->generic—>qualifier—>@Primary–>@Priority–>dependencyName}->
* ->{@link DefaultListableBeanFactory#resolveMultipleBeans 这里判断一下需要注入的类型stream,Array,Collection,Map}
* ->{@link DefaultListableBeanFactory#findAutowireCandidates
* -> {@link BeanFactoryUtils#beanNamesForTypeIncludingAncestors(ListableBeanFactory, Class, boolean, boolean)} 这里获取beanName(可能是程序猿自己设定的)作为key
* -> {@link DefaultListableBeanFactory#addCandidateEntry(Map, String, DependencyDescriptor, Class)} 这里回去被注入属性的类并封装在一个Map中 返回
* -> {@link DefaultListableBeanFactory#determineAutowireCandidate(Map, DependencyDescriptor)} 如果返回的Map的size>1(同一个beanName) 就在这个方法中选举出优先级最高的,如果不存在则判断有没有属性是
* 选举条件primary优先,其次是priority ,然后是实现以下接口中的一个
* {@link org.springframework.context.ApplicationEventPublisher}
* {@link org.springframework.beans.factory.BeanFactory}
* {@link org.springframework.context.ApplicationContext}
* {@link org.springframework.core.io.ResourceLoader}
* -> {@link DependencyDescriptor#resolveCandidate(String, Class, BeanFactory) 这里就是解决循环注入体现了,方法里面实现只有一句话beanFactory.getBean(beanName),这里beanName是被注入的Bean的Name,
* 这就回到getBean方法,相当于使用这个被注入的属性的beanName (以下称为B) 去创建一遍这个Bean B也执行一遍Bean A一样
* 的创建过程,在执行到 {@link DefaultSingletonBeanRegistry#getSingleton(String)这个方法对于Bean B来说也是首次进入因此,
* 在{@link DefaultSingletonBeanRegistry#singletonObjects 找不到Bean B的缓存}},往下执行,在重载的{@link DefaultSingletonBeanRegistry#getSingleton(String, ObjectFactory)}
* 方法中也会调用{@link DefaultSingletonBeanRegistry#beforeSingletonCreation}会将当前正在创建Bena加入到{@link singletonsCurrentlyInCreation}缓存中
* ( PS:这时之前正在创建的Bean A 和Bean B都在这里)
* 然后Bean B继续执行构造方法推断 -> 实例化 -> 注入的元数据类型合并-> 循环依赖判断-> 循环依赖缓存->属性注入,当运行到属性注入
* {@link AbstractAutowireCapableBeanFactory#populateBean } ->…省略部分…->又到了{@link DependencyDescriptor#resolveCandidate(String, Class, BeanFactory)}-> beanFactory.getBean(beanName)
* ->{@link DefaultSingletonBeanRegistry#getSingleton(String)}此时的beanName又变成Bean A 这个时候由于之前Bean A是第二次进入这个方法了,这也解释了为什么在一个Bean创建之初就会先这个getSingleton
* 方法判断一下Bean是否存在已久存在的状态。
* 回到Bean A在Bean A创建时开启了循环依赖的支持所以会在{@link singletonFactories}存在Bean A的ObjectFactorie可以直接从{@link DefaultSingletonBeanRegistry#getSingleton(String)}中调用
* ObjectFactory参数的lambd表达式来获取的方法后返回,并将Bean A放入{@link earlySingletonObjects}缓存在{@link singletonFactories}中remove,接着走的代码就和之前不一样了,Bean A已被缓存了
* 并返回了,代码会进入if (sharedInstance != null && args == null) 判断,进入{ {@link AbstractBeanFactory#getObjectForBeanInstance(Object, String, String, RootBeanDefinition)}
* (depend这些先不管)方法而不会去else判断在次创建了;开始返回
* {@link DependencyDescriptor#resolveCandidate(String, Class, BeanFactory)}->
* {@link DefaultListableBeanFactory#doResolveDependency -> {@link DefaultListableBeanFactory#resolveDependency(DependencyDescriptor, String, Set, TypeConverter)}}->
* {@link AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement#inject(Object, String, PropertyValues) -> field.set(bean, value)}->
* {@link InjectionMetadata#inject(Object, String, PropertyValues)->
* {@link AbstractAutowireCapableBeanFactory#populateBean} 返回到这里以后Bean B中的Bean A属性已经被注入Bean B继续创建
* {@link AbstractAutowireCapableBeanFactory#doCreateBean(String, RootBeanDefinition, Object[])}方法会执行下一步->
* {@link AbstractAutowireCapableBeanFactory#initializeBean(String, Object, RootBeanDefinition)}这里首先是判断System.getSecurityManager()一般为false,然后进入
* {@link AbstractAutowireCapableBeanFactory#invokeAwareMethods}放发给,
* 2.如果Bean实现了BeanNameAware调用Bean中的BeanNameAware.setBeanName()方法,如果bean是实现了BeanClassLoaderAware继续调用BeanClassLoaderAware.setBeanClassLoader(bcl)方法,
* 3.如过bean实现了BeanFactoryAware调用Bean中的BeanFactoryAware.setBeanFactory()方法,
* 如果该Bean实现了BeanFactoryAware接口;这个三个方法是Bean参数注入后的第2,3步生命周期;
* 接着往下wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);在这一步中有
* 0 = {@link org.springframework.context.support.ApplicationContextAwareProcessor#postProcessBeforeInitialization}
* 1 = {@link org.springframework.context.annotation.ConfigurationClassPostProcessor.ImportAwareBeanPostProcessor#postProcessBeforeInitialization}
* 2 = {@link org.springframework.context.support.PostProcessorRegistrationDelegate.BeanPostProcessorChecker#postProcessBeforeInitialization}
* 3 = {@link org.springframework.context.annotation.CommonAnnotationBeanPostProcessor#postProcessBeforeInitialization}
* 4 = {@link AutowiredAnnotationBeanPostProcessor#postProcessBeforeInitialization}
* 5 = {@link org.springframework.context.support.ApplicationListenerDetector#postProcessBeforeInitialization}
* 留个bean后置处理器 这一步第4步生命周期回调;接着往下
* {@link AbstractAutowireCapableBeanFactory#invokeInitMethods}5.调用Bean中的afterPropertiesSet方法,如果该Bean实现了InitializingBean接口;
* 调用Bean中的init-method,通常是在配置bean的时候指定了init-method,例如:<beanclass="beanClass"init-method=“init”>;这里是第5,6步生命周期回调在往下
* wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName)第7步生命周期回调,于第4步相同的类,只不过方法变成了postProcessAfterInitialization
* 0 = {@link org.springframework.context.support.ApplicationContextAwareProcessor#postProcessAfterInitialization}
* 1 = {@link org.springframework.context.annotation.ConfigurationClassPostProcessor.ImportAwareBeanPostProcessor##postProcessAfterInitialization}父类
* 2 = {@link org.springframework.context.support.PostProcessorRegistrationDelegate.BeanPostProcessorChecker#postProcessAfterInitialization}
* 3 = {@link org.springframework.context.annotation.CommonAnnotationBeanPostProcessor#postProcessAfterInitialization}
* 4 = {@link AutowiredAnnotationBeanPostProcessor#postProcessAfterInitialization}
* 5 = {@link org.springframework.context.support.ApplicationListenerDetector#postProcessAfterInitialization}
* 在回到{@link AbstractAutowireCapableBeanFactory#doCreateBean(String, RootBeanDefinition, Object[])}方法判断循环注入的返回值earlySingletonExposure这里==true
* 会在此调用 getSingleton(beanName, false),为false标识代码执行到这里,该Bean已经不允许在进入正在创建中的缓存池了即{@link earlySingletonObjects}缓存中,
* 如果是一个普通的Bean一些其他判断不用管,接着返回跳出 {@link AbstractAutowireCapableBeanFactory#initializeBean(String, Object, RootBeanDefinition)}方法回到
* {@link AbstractAutowireCapableBeanFactory#doCreateBean(String, RootBeanDefinition, Object[])}方法中往下执行到 afterSingletonCreation(beanName);注意这个时候的Bean还是Bean B
* 就是{@link AbstractAutowireCapableBeanFactory#afterSingletonCreation(String)}这个方法这里主要是清楚掉{@link singletonsCurrentlyInCreation 中对应当前创建即将完成的bean的缓存即Bean B
* 在往下 addSingleton(beanName, singletonObject);就是{@link AbstractAutowireCapableBeanFactory#addSingleton(String, Object)} 这里就是讲将完成的Bean缓存到单例池中,并将其从其他
* 两个缓存中remove:this.singletonObjects.put(beanName, singletonObject);this.singletonFactories.remove(beanName);this.earlySingletonObjects.remove(beanName);
* 到这里Bean B算是基本完成,然后在返回给正在创建中的Bean A,Bean A 在从{@link DependencyDescriptor#resolveCandidate(String, Class, BeanFactory)的下一步开始走,直到放入缓存池中
*/

package org.springframework.beans.factory.support;

import java.beans.PropertyEditor;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

import org.springframework.beans.;
import org.springframework.beans.factory.
;
import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor;
import org.springframework.beans.factory.annotation.InjectionMetadata;
import org.springframework.beans.factory.config.*;
import org.springframework.core.DecoratingClassLoader;
import org.springframework.core.NamedThreadLocal;
import org.springframework.core.ResolvableType;
import org.springframework.core.convert.ConversionService;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.util.StringValueResolver;

/**

  • Abstract base class for {@link org.springframework.beans.factory.BeanFactory}

  • implementations, providing the full capabilities of the

  • {@link org.springframework.beans.factory.config.ConfigurableBeanFactory} SPI.

  • Does not assume a listable bean factory: can therefore also be used

  • as base class for bean factory implementations which obtain bean definitions

  • from some backend resource (where bean definition access is an expensive operation).

  • This class provides a singleton cache (through its base class

  • {@link org.springframework.beans.factory.support.DefaultSingletonBeanRegistry},

  • singleton/prototype determination, {@link org.springframework.beans.factory.FactoryBean}

  • handling, aliases, bean definition merging for child bean definitions,

  • and bean destruction ({@link org.springframework.beans.factory.DisposableBean}

  • interface, custom destroy methods). Furthermore, it can manage a bean factory

  • hierarchy (delegating to the parent in case of an unknown bean), through implementing

  • the {@link org.springframework.beans.factory.HierarchicalBeanFactory} interface.

  • The main template methods to be implemented by subclasses are

  • {@link #getBeanDefinition} and {@link #createBean}, retrieving a bean definition

  • for a given bean name and creating a bean instance for a given bean definition,

  • respectively. Default implementations of those operations can be found in

  • {@link DefaultListableBeanFactory} and {@link AbstractAutowireCapableBeanFactory}.

  • @author Rod Johnson

  • @author Juergen Hoeller

  • @author Costin Leau

  • @author Chris Beams

  • @since 15 April 2001

  • @see #getBeanDefinition

  • @see #createBean

  • @see AbstractAutowireCapableBeanFactory#createBean

  • @see DefaultListableBeanFactory#getBeanDefinition
    */
    public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {

    /** Parent bean factory, for bean inheritance support. */
    @Nullable
    private BeanFactory parentBeanFactory;

    /** ClassLoader to resolve bean class names with, if necessary. */
    @Nullable
    private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();

    /** ClassLoader to temporarily resolve bean class names with, if necessary. */
    @Nullable
    private ClassLoader tempClassLoader;

    /** Whether to cache bean metadata or rather reobtain it for every access. */
    private boolean cacheBeanMetadata = true;

    /** Resolution strategy for expressions in bean definition values. */
    @Nullable
    private BeanExpressionResolver beanExpressionResolver;

    /** Spring ConversionService to use instead of PropertyEditors. */
    @Nullable
    private ConversionService conversionService;

    /** Custom PropertyEditorRegistrars to apply to the beans of this factory. */
    private final Set propertyEditorRegistrars = new LinkedHashSet<>(4);

    /** Custom PropertyEditors to apply to the beans of this factory. */
    private final Map<Class<?>, Class<? extends PropertyEditor>> customEditors = new HashMap<>(4);

    /** A custom TypeConverter to use, overriding the default PropertyEditor mechanism. */
    @Nullable
    private TypeConverter typeConverter;

    /** String resolvers to apply e.g. to annotation attribute values. */
    private final List embeddedValueResolvers = new CopyOnWriteArrayList<>();

    /** BeanPostProcessors to apply in createBean. */
    private final List beanPostProcessors = new CopyOnWriteArrayList<>();

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值