在创建 bean 的实例对象时,会调用 (org.springframework.beans.factory.support)AbstractBeanFactory#doGetBean:
protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)throws BeansException {// 获取 bean 名称String beanName = transformedBeanName(name);Object beanInstance;// 从缓存中获取单例的 bean:获取单例对象的时候,会触发三级缓存的处理,原型模式和单例模式最大的区别就是,前者不会放入缓存// Eagerly check singleton cache for manually registered singletons.Object sharedInstance = getSingleton(beanName);// 如果获取到单例 bean(bean != null),则走下面代码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 实例是 FactoryBean 的 Bean 实例,则需要从 FactoryBean 的实例中产生一个对象实例beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);}else {// 如果没有获取到单例 bean (bean == null),就走下面的代码// 如果 <原型模式(prototype)> 的 bean 发生循环引用,则直接不处理,抛出异常 (大多数获取都是用的单例模式)// 原型模式是无法解决循环引用和循环依赖问题的 ...// Fail if we're already creating this bean instance:// We're assumably within a circular reference.if (isPrototypeCurrentlyInCreation(beanName)) {throw new BeanCurrentlyInCreationException(beanName);}// 调用父工厂去找一找这个 bean// 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 if (requiredType != null) {// No args -> delegate to standard getBean method.return parentBeanFactory.getBean(nameToLookup, requiredType);}else {return (T) parentBeanFactory.getBean(nameToLookup);}}// 类型检查是否唯一if (!typeCheckOnly) {markBeanAsCreated(beanName);}StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate").tag("beanName", name);//---------------------------- bean 处理核心 ----------Spring 中一个 try...catch() 基本上就是一个处理核心--------------------------------try {if (requiredType != null) {beanCreation.tag("beanType", requiredType::toString);}// 获取要实例化的 bean 的 BeanDefinition 对象RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);// 检查该 BeanDefinition 对象对应的 Bean 是否是抽象的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);try {getBean(dep);}catch (NoSuchBeanDefinitionException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"'" + beanName + "' depends on missing bean '" + dep + "'", ex);}}}// ---------------------------------------- 单例的 Bean---------------------------------------------------------------------------// Create bean instance.if (mbd.isSingleton()) {// 使用 lambuda 表达式来调用 getSingleton 方法获取一个单例对象// public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) 第二个参数传入一个匿名内部类sharedInstance = getSingleton(beanName, () -> {try {// 创建单例 Bean 的主要方法,创建一个单例 beanreturn 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;}});beanInstance = 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);}beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);}// -----------------------------------------------------------------------------// 既非单例也非多例,request 或者是 session 级别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);}});beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);}catch (IllegalStateException ex) {throw new ScopeNotActiveException(beanName, scopeName, ex);}}}//-------------------------------------------------------------------------------------------------------->catch (BeansException ex) {beanCreation.tag("exception", ex.getClass().toString());beanCreation.tag("message", String.valueOf(ex.getMessage()));cleanupAfterBeanCreationFailure(beanName);throw ex;}finally {beanCreation.end();}}return adaptBeanInstance(name, beanInstance, requiredType);}
在创建单例对象时,会先后进入两个方法,第一个会进入 (org.springframework.beans.factory.support)DefaultSingletonBeanRegistry#getSingleton:
/*** 获取单例对象*/public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {Assert.notNull(beanName, "Bean name must not be null");synchronized (this.singletonObjects) {Object singletonObject = this.singletonObjects.get(beanName);if (singletonObject == null) {if (this.singletonsCurrentlyInDestruction) {throw new BeanCreationNotAllowedException(beanName,"Singleton bean creation not allowed while singletons of this factory are in destruction " +"(Do not request a bean from a BeanFactory in a destroy method implementation!)");}if (logger.isDebugEnabled()) {logger.debug("Creating shared instance of singleton bean '" + beanName + "'");}// 创建之前,设置一个创建中的标识beforeSingletonCreation(beanName);boolean newSingleton = false;boolean recordSuppressedExceptions = (this.suppressedExceptions == null);if (recordSuppressedExceptions) {this.suppressedExceptions = new LinkedHashSet<>();}// ------------------------------- bean 创建流程完成 ---------------------------------------------------------try {// 调用匿名内部类获取单例对象// 该步骤的完成就意味着 bean 的创建流程完成singletonObject = singletonFactory.getObject();newSingleton = true;}// ----------------------------------------------------------/catch (IllegalStateException ex) {// Has the singleton object implicitly appeared in the meantime ->// if yes, proceed with it since the exception indicates that state.singletonObject = this.singletonObjects.get(beanName);if (singletonObject == null) {throw ex;}}catch (BeanCreationException ex) {if (recordSuppressedExceptions) {for (Exception suppressedException : this.suppressedExceptions) {ex.addRelatedCause(suppressedException);}}throw ex;}finally {if (recordSuppressedExceptions) {this.suppressedExceptions = null;}// 创建成功之后,删除创建中的标识,如果存在这个标识,就说明这个 bean 正在创建中afterSingletonCreation(beanName);}// 将创建的单例 bean 放入缓存中(总共三级缓存)if (newSingleton) {addSingleton(beanName, singletonObject);}}return singletonObject;}}
这里的 afterSingletonCreation(beanName) 的作用是根据 bean 创建一个标识,如果在 bean 创建时检测到已经存在 bean 的标识,就说明这个 bean 正在创建中,如果没有标识就说明 bean 已经创建完成;使用这个方法可以解决循环依赖的问题。
(org.springframework.beans.factory.support)DefaultSingletonBeanRegistry#afterSingletonCreation:
protected void afterSingletonCreation(String beanName) {if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");}}
(org.springframework.beans.factory.support)DefaultSingletonBeanRegistry$singletonsCurrentlyInCreation 是一个集合:
/*** 标记位 可以用这个 set 来判断对象是否在创建中*/private final Set<String> singletonsCurrentlyInCreation =Collections.newSetFromMap(new ConcurrentHashMap<>(16));
此集合可以用来存储 beanName,如果 beanName 在这个集合中,就说明这个 bean 对象正在创建中,如果不在就说明 bean 对象已经创建完成了。
随后会进入 (org.springframework.beans.factory.support)AbstractAutowireCapableBeanFactory#createBean:
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.Class<?> resolvedClass = resolveBeanClass(mbd, beanName);if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {mbdToUse = new RootBeanDefinition(mbd);mbdToUse.setBeanClass(resolvedClass);}// 处理方法覆盖// Prepare method overrides.try {mbdToUse.prepareMethodOverrides();}catch (BeanDefinitionValidationException ex) {throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),beanName, "Validation of method overrides failed", ex);}try {// 获取 BeanPostProcessor 的代理对象// InstantiationAwareBeanPostProcessor 接口对 bean 的实例化的干预处理// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.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);}}
进入 (org.springframework.beans.factory.support)AbstractAutowireCapableBeanFactory#doCreateBean:
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException {// Instantiate the bean.// Spring 中 ~Wrapper 都是装饰的意思,是 Spring 装饰模式的表现形式BeanWrapper instanceWrapper = null;if (mbd.isSingleton()) {instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);}// ------------------------------- bean 初始化第一步:默认调用无参函数构造实例化 Bean ---------------------------// 构造参数依赖注入,就是发生在这一步if (instanceWrapper == null) {instanceWrapper = createBeanInstance(beanName, mbd, args);}// 实例化后的 Bean 对象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.// ------------------------- 将第一步创建的对象放入 3 级缓存中 --------------------------------// 解决循环依赖的关键步骤boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&isSingletonCurrentlyInCreation(beanName));// 如果需要提前保留单例 Bean ,则将该 Bean 放入三级缓存中if (earlySingletonExposure) {if (logger.isTraceEnabled()) {logger.trace("Eagerly caching bean '" + beanName +"' to allow for resolving potential circular references");}// 将刚创建的 bean 放入三级缓存中 singleFactories(key 是 beanName,value 是 FactoryBean)// 此处使用了一个匿名内部类来表示 ObjectFactory () -> getEarlyBeanReference(beanName, mbd, bean)// 同时也把第一步创建的 bean 提前封装到了 getEarlyBeanReference 中addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));}// -------------------------------------------------------------------------------/// Initialize the bean instance.Object exposedObject = bean;try {// ----------------------------------- bean 初始化第二部:填充属性 (DI 依赖注入发生在此步骤) ----------------// 调用反射和内容去进行属性设置// 属性值需要进行类型转换populateBean(beanName, mbd, instanceWrapper);// ------------------------------------------------/// ------------------------------------- bean 初始化第三步:调用初始化方法,完成 bean 的初始化操作(AOP 发生在此步骤) ---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;}
此处完成了 bean 创建的三部曲,同时在第一步骤完成时,做了一个解决循环依赖的操作,此处存入缓存的条件是:
- 对象是否是单例
- 能不能允许循环引用
- 依赖 对象是否创建中 (此处就是指的上一步变量 singletonsCurrentlyInCreation)
如果符合上面的三个条件,就将创建的 bean 对象放入三级缓存中。
另外,在可以看到解决循环依赖的代码是位于 bean 创建的第一步骤 和 第二步骤之间,也就是位于 bean 实例化 和 bean 属性填充之间:
所以Spring 通过三级缓存来解决循环依赖,且只能解决Set 方法循环依赖,因为循环依赖解决操作是在对象创建之后才进行的。如果是构造方法循环依赖,是无法解决的,只能修改。
