首先,咱们在3.1 spring5源码系列--循环依赖 之 手写代码模拟spring循环依赖 中手写了循环依赖的实现. 这个实现就是模拟的spring的循环依赖. 目的是为了更容易理解spring源码.html
下面咱们就进入正题, 看看spring的循环依赖源码.spring
目标很明确了, 就是要看看spring如何解决循环依赖的. 设计模式
代码入口是refresh()#finishBeanFactoryInitialization(beanFactory);缓存
调用方法beanFactory.preInstantiateSingletons();实例化剩余的单例bean. 为何是剩余的?很显然咱们在上面已经实例化一部分了.好比配置类, postProcessor等.mvc
1 @Override
2 public void preInstantiateSingletons() throws BeansException { 3 if (logger.isTraceEnabled()) { 4 logger.trace("Pre-instantiating singletons in " + this); 5 } 6 7 8 // 获取容器中全部bean定义的名字 9 List<String> beanNames = new ArrayList<>(this.beanDefinitionNames); 10 11 // Trigger initialization of all non-lazy singleton beans... 12 /** 13 * 第一步: 循环bean定义的name 14 */ 15 for (String beanName : beanNames) { 16 // 获取bean定义 17 RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); 18 // 生产bean定义的条件: 不是抽象的, 是单例的, 不是懒加载的. 符合这个标准的, 最后才会调用getBean()生产bean 19 if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { 20 // 这里判断是否是工厂bean, 这里和BeanFactory不是一个意思, 判断当前这个bean是否实现了beanFactory的接口 21 if (isFactoryBean(beanName)) { 22 Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); 23 if (bean instanceof FactoryBean) { 24 final FactoryBean<?> factory = (FactoryBean<?>) bean; 25 boolean isEagerInit; 26 if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) { 27 isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>) 28 ((SmartFactoryBean<?>) factory)::isEagerInit, 29 getAccessControlContext()); 30 } 31 else { 32 isEagerInit = (factory instanceof SmartFactoryBean && 33 ((SmartFactoryBean<?>) factory).isEagerInit()); 34 } 35 if (isEagerInit) { 36 // 获取bean 37 getBean(beanName); 38 } 39 } 40 } 41 else {
// 第二步: 调用bean定义 42 getBean(beanName); 43 } 44 } 45 } 46 47 // Trigger post-initialization callback for all applicable beans... 48 /** 49 * 循环bean定义的name 50 */ 51 for (String beanName : beanNames) { 52 // 从缓存中获得实例instance 53 Object singletonInstance = getSingleton(beanName); 54 if (singletonInstance instanceof SmartInitializingSingleton) { 55 final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance; 56 if (System.getSecurityManager() != null) { 57 AccessController.doPrivileged((PrivilegedAction<Object>) () -> { 58 smartSingleton.afterSingletonsInstantiated(); 59 return null; 60 }, getAccessControlContext()); 61 } 62 else { 63 smartSingleton.afterSingletonsInstantiated(); 64 } 65 } 66 } 67 }
咱们注意代码注释中, 生产bean定义的条件: 不是抽象的, 是单例的, 不是懒加载的. 符合这个标准的, 最后才会调用getBean()生产beanapp
到目前为止,咱们完成了上图源码图的第一部分:异步
接下来看看getBean().doGetBean()方法ide
1 protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
2 @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException { 3 4 // 第一步: 转换bean name. 在这里传入进来的name多是别名, 也有多是工厂bean的name, 因此在这里进行一个转换 5 final String beanName = transformedBeanName(name); 6 Object bean; 7 8 // Eagerly check singleton cache for manually registered singletons. 9 // 第二步: 尝试去缓存中获取对象, 若是没有获取到就建立bean 10 Object sharedInstance = getSingleton(beanName); 11 if (sharedInstance != null && args == null) { 12 if (logger.isTraceEnabled()) { 13 //判断当前类是不是正在建立中 14 if (isSingletonCurrentlyInCreation(beanName)) { 15 logger.trace("Returning eagerly cached instance of singleton bean '" + beanName + 16 "' that is not fully initialized yet - a consequence of a circular reference"); 17 } 18 else { 19 logger.trace("Returning cached instance of singleton bean '" + beanName + "'"); 20 } 21 } 22 bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); 23 } 24 25 else { 26 // Fail if we're already creating this bean instance: 27 // We're assumably within a circular reference. 28 /** 29 * 判断当前的bean是否是多例, 若是是这抛出异常 30 * 31 * 判断当前这个bean是否是多例bean. 若是配置了@Scope("prototype") 就表示这是一个多例的bean 32 * spring 只能解决单例对象的setter注入的循环依赖, 不能解决构造器注入 33 * 34 * 若是是多例的bean, 当前正在建立bean, 也会抛出异常---这也是循环依赖的问题 35 */ 36 if (isPrototypeCurrentlyInCreation(beanName)) { 37 throw new BeanCurrentlyInCreationException(beanName); 38 } 39 40 /** 41 * 下面这段代码是关于子父容器的, 只有spring mvc继承自spring, 才会有子父容器的问题. 42 */ 43 // Check if bean definition exists in this factory. 44 BeanFactory parentBeanFactory = getParentBeanFactory(); 45 if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { 46 // Not found -> check parent. 47 String nameToLookup = originalBeanName(name); 48 if (parentBeanFactory instanceof AbstractBeanFactory) { 49 return ((AbstractBeanFactory) parentBeanFactory).doGetBean( 50 nameToLookup, requiredType, args, typeCheckOnly); 51 } 52 else if (args != null) { 53 // Delegation to parent with explicit args. 54 return (T) parentBeanFactory.getBean(nameToLookup, args); 55 } 56 else if (requiredType != null) { 57 // No args -> delegate to standard getBean method. 58 return parentBeanFactory.getBean(nameToLookup, requiredType); 59 } 60 else { 61 return (T) parentBeanFactory.getBean(nameToLookup); 62 } 63 } 64 65 /** 66 * 方法参数typeCheckOnly是用来判断#getBean()方法时, 表示是否为仅仅进行类型检查, 67 * 若是不只仅作类型检查, 而是建立bean对象, 则须要调用#markBeanAsCreated(String name) 68 * 69 */ 70 if (!typeCheckOnly) { 71 markBeanAsCreated(beanName); 72 } 73 74 try { 75 final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); 76 checkMergedBeanDefinition(mbd, beanName, args); 77 78 // Guarantee initialization of beans that the current bean depends on. 79 /** 80 * 如今有两个bean1, bean2 , 加载的时候调用的是bean1, bean2. 但若是咱们想要bean2优先加载, 就使用@DependOn注解 81 * 用来解析带有dependOn注解的类 82 */ 83 String[] dependsOn = mbd.getDependsOn(); 84 if (dependsOn != null) { 85 for (String dep : dependsOn) { 86 if (isDependent(beanName, dep)) { 87 throw new BeanCreationException(mbd.getResourceDescription(), beanName, 88 "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'"); 89 } 90 registerDependentBean(dep, beanName); 91 try { 92 getBean(dep); 93 } 94 catch (NoSuchBeanDefinitionException ex) { 95 throw new BeanCreationException(mbd.getResourceDescription(), beanName, 96 "'" + beanName + "' depends on missing bean '" + dep + "'", ex); 97 } 98 } 99 } 100 101 // Create bean instance. 102 /** 103 * 第三步: 建立单例bean实例 104 */ 105 if (mbd.isSingleton()) { // 处理单例bean 106 /** 107 * 这里getSingleton()和上面的getSigleton不同, 上面的是从一级缓存中拿. 108 * 这个getSingleton()就办了一件事: 将bean设置为正在建立的状态. 这个状态很重要, 若是出现循环依赖, 发现bean正在建立, 就不会再建立了 109 */ 110 sharedInstance = getSingleton(beanName, () -> { 111 try { 112 return createBean(beanName, mbd, args); 113 } 114 catch (BeansException ex) { 115 // Explicitly remove instance from singleton cache: It might have been put there 116 // eagerly by the creation process, to allow for circular reference resolution. 117 // Also remove any beans that received a temporary reference to the bean. 118 destroySingleton(beanName); 119 throw ex; 120 } 121 }); 122 // 获得bean实例对象 123 bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); 124 } 125 126 else if (mbd.isPrototype()) { // 处理多例bean 127 // It's a prototype -> create a new instance. 128 Object prototypeInstance = null; 129 try { 130 // 当前正在建立多例bean 131 beforePrototypeCreation(beanName); 132 // 执行建立bean 133 prototypeInstance = createBean(beanName, mbd, args); 134 } 135 finally { 136 afterPrototypeCreation(beanName); 137 } 138 // 获取bean实例对象 139 bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); 140 } 141 142 else { // 处理其余类型的bean 143 String scopeName = mbd.getScope(); 144 final Scope scope = this.scopes.get(scopeName); 145 if (scope == null) { 146 throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'"); 147 } 148 try { 149 Object scopedInstance = scope.get(beanName, () -> { 150 beforePrototypeCreation(beanName); 151 try { 152 return createBean(beanName, mbd, args); 153 } 154 finally { 155 afterPrototypeCreation(beanName); 156 } 157 }); 158 bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd); 159 } 160 catch (IllegalStateException ex) { 161 throw new BeanCreationException(beanName, 162 "Scope '" + scopeName + "' is not active for the current thread; consider " + 163 "defining a scoped proxy for this bean if you intend to refer to it from a singleton", 164 ex); 165 } 166 } 167 } 168 catch (BeansException ex) { 169 cleanupAfterBeanCreationFailure(beanName); 170 throw ex; 171 } 172 }
在这里, 首先从缓存中获取bean, 看缓存中是否已经存在了函数
Object sharedInstance = getSingleton(beanName);
而后, 若是缓存中已经存在了,那么久直接取出来. 代码以下: post
if (sharedInstance != null && args == null) {
if (logger.isTraceEnabled()) { //判断当前bean是不是正在建立中(单例bean) 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 = getObjectForBeanInstance(sharedInstance, name, beanName, null); }
若是是空, 就说明是第一次建立, 执行else的部分
已是正在建立了, 说明这至少是第二次了, 这里处理的是单例bean的循环依赖, 不处理多例bean的循环依赖, 因此抛出异常
对应的代码是这一句
// Fail if we're already creating this bean instance:
27 // We're assumably within a circular reference.
28 /**
29 * 判断当前的bean是否是多例, 若是是这抛出异常
30 *
31 * 判断当前这个bean是否是多例bean. 若是配置了@Scope("prototype") 就表示这是一个多例的bean
32 * spring 只能解决单例对象的setter注入的循环依赖, 不能解决构造器注入
33 *
34 * 若是是多例的bean, 当前正在建立bean, 也会抛出异常---这也是循环依赖的问题
35 */
36 if (isPrototypeCurrentlyInCreation(beanName)) {
37 throw new BeanCurrentlyInCreationException(beanName); 38 }
那么, 接下来就是首次建立bean. 首次建立的bean有三种状况:
第一种, 这个bean是单例的.
第二种, 这个bean是多例的.
第三种. 其余类型
对应的代码就是这一块. 有行号, 能够和上面一一对应上
// Create bean instance.
102 /**
103 * 第三步: 建立单例bean实例
104 */
105 if (mbd.isSingleton()) { // 处理单例bean
106 /**
107 * 这里getSingleton()和上面的getSigleton不同, 上面的是从一级缓存中拿.
108 * 这个getSingleton()就办了一件事: 将bean设置为正在建立的状态. 这个状态很重要, 若是出现循环依赖, 发现bean正在建立, 就不会再建立了
109 */
110 sharedInstance = getSingleton(beanName, () -> {
111 try { 112 return createBean(beanName, mbd, args); 113 } 114 catch (BeansException ex) { 115 // Explicitly remove instance from singleton cache: It might have been put there 116 // eagerly by the creation process, to allow for circular reference resolution. 117 // Also remove any beans that received a temporary reference to the bean. 118 destroySingleton(beanName); 119 throw ex; 120 } 121 }); 122 // 获得bean实例对象 123 bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); 124 } 125 126 else if (mbd.isPrototype()) { // 处理多例bean 127 // It's a prototype -> create a new instance. 128 Object prototypeInstance = null; 129 try { 130 // 当前正在建立多例bean 131 beforePrototypeCreation(beanName); 132 // 执行建立bean 133 prototypeInstance = createBean(beanName, mbd, args); 134 } 135 finally { 136 afterPrototypeCreation(beanName); 137 } 138 // 获取bean实例对象 139 bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); 140 } 141 142 else { // 处理其余类型的bean 143 String scopeName = mbd.getScope(); 144 final Scope scope = this.scopes.get(scopeName); 145 if (scope == null) { 146 throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'"); 147 } 148 try { 149 Object scopedInstance = scope.get(beanName, () -> { 150 beforePrototypeCreation(beanName); 151 try { 152 return createBean(beanName, mbd, args); 153 } 154 finally { 155 afterPrototypeCreation(beanName); 156 } 157 }); 158 bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd); 159 } 160 catch (IllegalStateException ex) { 161 throw new BeanCreationException(beanName, 162 "Scope '" + scopeName + "' is not active for the current thread; consider " + 163 "defining a scoped proxy for this bean if you intend to refer to it from a singleton", 164 ex); 165 } 166 }
咱们的重点研究对象是单例bean. 因此,重点看单例bean的实现
105 if (mbd.isSingleton()) { // 处理单例bean
106 /**
107 * 这里getSingleton()和上面的getSigleton不同, 上面的是从一级缓存中拿.
108 * 这个getSingleton()就办了一件事: 将bean设置为正在建立的状态. 这个状态很重要, 若是出现循环依赖, 发现bean正在建立, 就不会再建立了
109 */
110 sharedInstance = getSingleton(beanName, () -> {
111 try {
112 return createBean(beanName, mbd, args);
113 }
114 catch (BeansException ex) {
115 // Explicitly remove instance from singleton cache: It might have been put there
116 // eagerly by the creation process, to allow for circular reference resolution.
117 // Also remove any beans that received a temporary reference to the bean.
118 destroySingleton(beanName);
119 throw ex;
120 }
121 });
122 // 获得bean实例对象
123 bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
124 }
这里的重点是调用了getSingleton(beanName, FactoryObject); FactoryObject是一个接口. 定义了一个钩子方法getObject().
这个接口在这里这是进行了定义, 并不会执行. 何时执行呢? 后面调用的时候执行.
下面来看看getSingleton()方法, 钩子方法也是在这里被调用的.
1 public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
2 Assert.notNull(beanName, "Bean name must not be null"); 3 synchronized (this.singletonObjects) { 4 // 第一步: 从一级缓存中获取单例对象 5 Object singletonObject = this.singletonObjects.get(beanName); 6 if (singletonObject == null) { 7 if (this.singletonsCurrentlyInDestruction) { 8 throw new BeanCreationNotAllowedException(beanName, 9 "Singleton bean creation not allowed while singletons of this factory are in destruction " + 10 "(Do not request a bean from a BeanFactory in a destroy method implementation!)"); 11 } 12 if (logger.isDebugEnabled()) { 13 logger.debug("Creating shared instance of singleton bean '" + beanName + "'"); 14 } 15 // 第二步: 将bean添加到singletonsCurrentlyInCreation中, 表示bean正在建立 16 beforeSingletonCreation(beanName); 17 boolean newSingleton = false; 18 boolean recordSuppressedExceptions = (this.suppressedExceptions == null); 19 if (recordSuppressedExceptions) { 20 this.suppressedExceptions = new LinkedHashSet<>(); 21 } 22 try { 23 // 第三步: 这里调用getObject()钩子方法, 就会回调匿名函数, 调用singletonFactory的createBean() 24 singletonObject = singletonFactory.getObject(); 25 newSingleton = true; 26 } 27 catch (IllegalStateException ex) { 28 // Has the singleton object implicitly appeared in the meantime -> 29 // if yes, proceed with it since the exception indicates that state. 30 singletonObject = this.singletonObjects.get(beanName); 31 if (singletonObject == null) { 32 throw ex; 33 } 34 } 35 catch (BeanCreationException ex) { 36 if (recordSuppressedExceptions) { 37 for (Exception suppressedException : this.suppressedExceptions) { 38 ex.addRelatedCause(suppressedException); 39 } 40 } 41 throw ex; 42 } 43 finally { 44 if (recordSuppressedExceptions) { 45 this.suppressedExceptions = null; 46 } 47 afterSingletonCreation(beanName); 48 } 49 if (newSingleton) { 50 addSingleton(beanName, singletonObject); 51 } 52 } 53 return singletonObject; 54 } 55 }
这里是调用getBean().
第一步: 去一级缓存中取成熟的单例bean. 若是拿到了, 就直接返回. 若是没拿到. 那么执行建立.
第二步: 在建立以前, 先把这个bean放入到正在建立的单例bean集合中. 标记这个bean正在建立中
第三步: 就是调用钩子方法getObject()了. 这个方法的方法体是在上面定义的. 其内容是去建立实例
sharedInstance = getSingleton(beanName, () -> {
try { // 这里定义了一个钩子函数. 此时只是定义, 并不执行. 在真正须要建立bean的地方才会执行 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的过程
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { /** * 第一步: 实例化 * 这里面的调用链很是深, 后面再看 * bean实例化有两种方式 * 1. 使用反射: 使用反射也有两种方式, * a. 经过无参构造函数 (默认的方式) * 从beanDefinition中能够获得beanClass, * ClassName = BeanDefinition.beanClass * Class clazz = Class.forName(ClassName); * clazz.newInstance(); * 这样就能够实例化bean了 * * b. 经过有参函数. * ClassName = BeanDefinition.beanClass * Class clazz = Class.forName(ClassName); * Constractor con = class.getConstractor(args....) * con.newInstance(); * * 2. 使用工厂 * 咱们使用@Bean的方式, 就是使用的工厂模式, 本身控制实例化过程 * */ instanceWrapper = createBeanInstance(beanName, mbd, args); } // 这里使用了装饰器的设计模式 final Object bean = instanceWrapper.getWrappedInstance(); Class<?> beanType = instanceWrapper.getWrappedClass(); if (beanType != NullBean.class) { mbd.resolvedTargetType = beanType; } // Allow post-processors to modify the merged bean definition. // 容许后置处理器修改已经合并的beanDefinition 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; } } /** * 缓存单例bean到三级缓存中, 以防止循环依赖 * 判断是不是早期引用的bean, 若是是, 则容许提早暴露引用
* * 判断是否可以早起暴露的条件 * 1. 是单例 * 2. 容许循环依赖 * 3. 正在建立的bean */ 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"); } // 把咱们的早期对象包装成一个singletonFactory对象, 该对象提供了getObject()方法, 把静态的bean放到三级缓存中去了. addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); } // Initialize the bean instance. Object exposedObject = bean; try { // 第二步:填充属性, 给属性赋值(调用set方法) 这里也是调用的后置处理器 populateBean(beanName, mbd, instanceWrapper); // 第三步: 初始化. 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) { // 去缓存中获取到咱们的对象 因为传递的allowEarlyReference是false, 要求只能在一级二级缓存中取 // 正常的普通的bean(不存在循环依赖的bean) 建立的过程当中, 不会把三级缓存提高到二级缓存中. 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, 实例化的方式有两种. 一种是经过反射, 另外一种是经过动态代理
/**
* 第一步: 实例化
* 这里面的调用链很是深, 后面再看
* bean实例化有两种方式
* 1. 使用反射: 使用反射也有两种方式,
* a. 经过无参构造函数 (默认的方式)
* 从beanDefinition中能够获得beanClass,
* ClassName = BeanDefinition.beanClass
* Class clazz = Class.forName(ClassName);
* clazz.newInstance();
* 这样就能够实例化bean了
*
* b. 经过有参函数.
* ClassName = BeanDefinition.beanClass
* Class clazz = Class.forName(ClassName);
* Constractor con = class.getConstractor(args....)
* con.newInstance();
*
* 2. 使用工厂
* 咱们使用@Bean的方式, 就是使用的工厂模式, 本身控制实例化过程
*
*/
instanceWrapper = createBeanInstance(beanName, mbd, args);
判断是不是早期暴露的bean. 知足早期暴露的bean的三个条件是
1. 是单例的
2. 容许循环依赖
3. bean已是处在正在建立中的行列了.
/* 判断是否可以早起暴露的条件
* 1. 是单例
* 2. 容许循环依赖
* 3. 正在建立的bean
*/
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName));
// 第二步:填充属性, 给属性赋值(调用set方法) 这里也是调用的后置处理器 populateBean(beanName, mbd, instanceWrapper);
在这里会判断, 是否带有@Autowired的属性. 分为两种一种是Name,一种是Type
@SuppressWarnings("deprecation") // for postProcessPropertyValues
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; } } } } PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null); // 判断属性是否有Autowired注解 int resolvedAutowireMode = mbd.getResolvedAutowireMode(); // Autowired是根据名字或者根据类型 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; } ...... }
若是按照名字注入
protected void autowireByName(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw); for (String propertyName : propertyNames) { if (containsBean(propertyName)) { // 调用getBean Object bean = getBean(propertyName); pvs.add(propertyName, bean); registerDependentBean(propertyName, beanName); if (logger.isTraceEnabled()) { logger.trace("Added autowiring by name from bean name '" + beanName + "' via property '" + propertyName + "' to bean named '" + propertyName + "'"); } } else { if (logger.isTraceEnabled()) { logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName + "' by name: no matching bean found"); } } } }
会再次调用getBean方法. 构建bean. 这是就有可能出现循环依赖了.
按类型注入也是同样的.
只是解析bean的方式不一样.
// 第三步: 初始化. exposedObject = initializeBean(beanName, exposedObject, mbd);
在初始化bean的时候, 会调用不少的aware. 还会调用init-method方法. 以及bean的后置处理器.
/**
* 初始化完成之后, 判断是不是早期的对象
* 是循环依赖. 才会走进这里来
*/
if (earlySingletonExposure) {
// 去缓存中获取到咱们的对象 因为传递的allowEarlyReference是false, 要求只能在一级二级缓存中取
// 正常的普通的bean(不存在循环依赖的bean) 建立的过程当中, 不会把三级缓存提高到二级缓存中.
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."); } } } }
removeSingletonIfCreatedForTypeCheckOnly调用方法, 删除缓存.
这既是getBean()整个的过程. 中间还有不少细节, 没有往里面深刻的看, 由于spring代码很是的深, 看的太深就忘了咱们的目标了. 结合以前手写的spring循环依赖的思想看, 仍是能够看得懂的.
二级缓存用来存放早期的bean, 也就是没有被属性赋值和初始化的bean
三级缓存的主要做用是用来解耦. 解耦后异步调用, 三级缓存中保存的是钩子方法,也就是一个接口。在使用的时候调用bean的后置处理器
答案是没有. 由于构造函数是在实例化的时候构建的. 这个时候bean都尚未建立, 因此没有办法处理循环依赖.若是出现构造函数的循环依赖, 是会直接报错的..
也是没有的, 由于咱们会判断, 若是是多例, 那么会抛出异常
1 /**
2 * 第二步: 判断当前bean是不是正在建立中的多例bean, 若是是就抛出异常
3 *
4 * 2. 判断当前这个bean是否是多例bean. 若是配置了@Scope("prototype") 就表示这是一个多例的bean
5 * spring 只能解决单例对象的setter注入的循环依赖, 不能解决构造器注入
6 *
7 * 若是是多例的bean, 当前正在建立bean, 也会抛出异常---这也是循环依赖的问题
8 */
9 if (isPrototypeCurrentlyInCreation(beanName)) {
10 throw new BeanCurrentlyInCreationException(beanName); 11 }