參考博客: http://www.javashuo.com/article/p-qnshsajb-bg.htmlspring
https://blog.csdn.net/qq924862077/article/details/73926268緩存
主要解決方式:使用三級緩存ide
singletonObjects: 一級緩存, Cache of singleton objects: bean name --> bean instanceui
earlySingletonObjects: 二級緩存, Cache of early singleton objects: bean name --> bean instance 提早曝光的BEAN緩存this
singletonFactories: 三級緩存, Cache of singleton factories: bean name --> ObjectFactoryspa
源碼片斷以下:.net
org.springframework.beans.factory.support.AbstractBeanFactory.doGetBeanprototype
1 protected <T> T doGetBean( 2 final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly) 3 throws BeansException { 4 5 final String beanName = transformedBeanName(name); 6 Object bean; 7 8 // Eagerly check singleton cache for manually registered singletons. 9 Object sharedInstance = getSingleton(beanName); 10 if (sharedInstance != null && args == null) { 11 if (logger.isDebugEnabled()) { 12 if (isSingletonCurrentlyInCreation(beanName)) { 13 logger.debug("Returning eagerly cached instance of singleton bean '" + beanName + 14 "' that is not fully initialized yet - a consequence of a circular reference"); 15 } 16 else { 17 logger.debug("Returning cached instance of singleton bean '" + beanName + "'"); 18 } 19 } 20 bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); 21 } 22 23 else { 24 // Fail if we're already creating this bean instance: 25 // We're assumably within a circular reference. 26 if (isPrototypeCurrentlyInCreation(beanName)) { 27 throw new BeanCurrentlyInCreationException(beanName); 28 } 29 30 // Check if bean definition exists in this factory. 31 BeanFactory parentBeanFactory = getParentBeanFactory(); 32 if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { 33 // Not found -> check parent. 34 String nameToLookup = originalBeanName(name); 35 if (args != null) { 36 // Delegation to parent with explicit args. 37 return (T) parentBeanFactory.getBean(nameToLookup, args); 38 } 39 else { 40 // No args -> delegate to standard getBean method. 41 return parentBeanFactory.getBean(nameToLookup, requiredType); 42 } 43 } 44 45 if (!typeCheckOnly) { 46 markBeanAsCreated(beanName); 47 } 48 49 try { 50 final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); 51 checkMergedBeanDefinition(mbd, beanName, args); 52 53 // Guarantee initialization of beans that the current bean depends on. 54 String[] dependsOn = mbd.getDependsOn(); 55 if (dependsOn != null) { 56 for (String dep : dependsOn) { 57 if (isDependent(beanName, dep)) { 58 throw new BeanCreationException(mbd.getResourceDescription(), beanName, 59 "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'"); 60 } 61 registerDependentBean(dep, beanName); 62 getBean(dep); 63 } 64 } 65 66 // Create bean instance. 67 if (mbd.isSingleton()) { 68 sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() { 69 @Override 70 public Object getObject() throws BeansException { 71 try { 72 return createBean(beanName, mbd, args); 73 } 74 catch (BeansException ex) { 75 // Explicitly remove instance from singleton cache: It might have been put there 76 // eagerly by the creation process, to allow for circular reference resolution. 77 // Also remove any beans that received a temporary reference to the bean. 78 destroySingleton(beanName); 79 throw ex; 80 } 81 } 82 }); 83 bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); 84 } 85 86 else if (mbd.isPrototype()) { 87 // It's a prototype -> create a new instance. 88 Object prototypeInstance = null; 89 try { 90 beforePrototypeCreation(beanName); 91 prototypeInstance = createBean(beanName, mbd, args); 92 } 93 finally { 94 afterPrototypeCreation(beanName); 95 } 96 bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); 97 } 98 99 else { 100 String scopeName = mbd.getScope(); 101 final Scope scope = this.scopes.get(scopeName); 102 if (scope == null) { 103 throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'"); 104 } 105 try { 106 Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() { 107 @Override 108 public Object getObject() throws BeansException { 109 beforePrototypeCreation(beanName); 110 try { 111 return createBean(beanName, mbd, args); 112 } 113 finally { 114 afterPrototypeCreation(beanName); 115 } 116 } 117 }); 118 bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd); 119 } 120 catch (IllegalStateException ex) { 121 throw new BeanCreationException(beanName, 122 "Scope '" + scopeName + "' is not active for the current thread; consider " + 123 "defining a scoped proxy for this bean if you intend to refer to it from a singleton", 124 ex); 125 } 126 } 127 } 128 catch (BeansException ex) { 129 cleanupAfterBeanCreationFailure(beanName); 130 throw ex; 131 } 132 } 133 134 // Check if required type matches the type of the actual bean instance. 135 if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) { 136 try { 137 return getTypeConverter().convertIfNecessary(bean, requiredType); 138 } 139 catch (TypeMismatchException ex) { 140 if (logger.isDebugEnabled()) { 141 logger.debug("Failed to convert bean '" + name + "' to required type '" + 142 ClassUtils.getQualifiedName(requiredType) + "'", ex); 143 } 144 throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); 145 } 146 } 147 return (T) bean; 148 }
總結:簡單來講Spring不支持原型bean的循環依賴debug