3.2spring源码系列----循环依赖源码分析 3.1 spring5源码系列--循环依赖 之 手写代码模拟spring循环依赖

前端之家收集整理的这篇文章主要介绍了3.2spring源码系列----循环依赖源码分析 3.1 spring5源码系列--循环依赖 之 手写代码模拟spring循环依赖前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

首先,我们在3.1 spring5源码系列--循环依赖 之 手写代码模拟spring循环依赖 中手写了循环依赖的实现. 这个实现就是模拟的spring的循环依赖. 目的是为了更容易理解spring源码.

下面我们就进入正题,看看spring的循环依赖源码.

 

一、getBean整体流程

 

目标很明确了,就是要看看spring如何解决循环依赖的. 

代码入口是refresh()#finishbeanfactoryInitialization(beanfactory);

二、拆解研究流程中的每一步

调用方法beanfactory.preInstantiateSingletons();实例化剩余的单例bean. 为什么是剩余的?很显然我们在上面已经实例化一部分了.比如配置类,postProcessor等.

2.1 入口

  1. 1 @Override
  2. 2 public void preInstantiateSingletons() throws BeansException {
  3. 3 if (logger.isTraceEnabled()) {
  4. 4 logger.trace("Pre-instantiating singletons in " + this);
  5. 5 }
  6. 6
  7. 7
  8. 8 // 获取容器中所有bean定义的名字
  9. 9 List<String> beanNames = new ArrayList<>(.beanDefinitionNames);
  10. 10
  11. 11 Trigger initialization of all non-lazy singleton beans...
  12. 12 /**
  13. 13 * 第一步: 循环bean定义的name
  14. 14 */
  15. 15 for (String beanName : beanNames) {
  16. 16 获取bean定义
  17. 17 RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
  18. 18 生产bean定义的条件: 不是抽象的,是单例的,不是懒加载的. 符合这个标准的,最后才会调用getBean()生产bean
  19. 19 if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
  20. 20 这里判断是不是工厂bean,这里和beanfactory不是一个意思,判断当前这个bean是否实现了beanfactory的接口
  21. 21 (isfactorybean(beanName)) {
  22. 22 Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
  23. 23 (bean instanceof factorybean) {
  24. 24 final factorybean<?> factory = (factorybean<?>) bean;
  25. 25 boolean isEagerInit;
  26. 26 if (System.getSecurityManager() != null && factory instanceof Smartfactorybean) {
  27. 27 isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
  28. 28 ((Smartfactorybean<?>) factory)::isEagerInit,29 getAccessControlContext());
  29. 30 }
  30. 31 else {
  31. 32 isEagerInit = (factory instanceof Smartfactorybean &&
  32. 33 ((Smartfactorybean<?>) factory).isEagerInit());
  33. 3435 (isEagerInit) {
  34. 36 获取bean
  35. 37 getBean(beanName);
  36. 3839 }
  37. 40 }
  38. 41 {
  39.               // 第二步: 调用bean定义
  40. 42 getBean(beanName);
  41. 4344 }
  42. 45 }
  43. 46
  44. 47 Trigger post-initialization callback for all applicable beans...
  45. 48
  46. 51 52 从缓存中得到实例instance
  47. 53 Object singletonInstance = getSingleton(beanName);
  48. 54 (singletonInstance instanceof SmartInitializingSingleton) {
  49. 55 final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
  50. 56 null) {
  51. 57 AccessController.doPrivileged((PrivilegedAction<Object>) () ->58 smartSingleton.afterSingletonsInstantiated();
  52. 59 return ;
  53. 60 },getAccessControlContext());
  54. 6162 63 smartSingleton.afterSingletonsInstantiated();
  55. 64656667 }

 

首先,循环bean定义,这和我们模拟spring循环的第一步是一样的. 

第二步: 判断从BeanDefinitionMap中取出来的这个bean是否满足生产bean的条件

我们注意代码注释中, 生产bean定义的条件: 不是抽象的,最后才会调用getBean()生产bean

然后:调用getBean()

到目前为止,我们完成了上图源码图的第一部分:

 

 

 2.2 创建bean前的准备工作

接下来看看getBean().doGetBean()方法

 

  1. 1 protected <T> T doGetBean(final String name,@Nullable final Class<T> requiredType,1)">2 @Nullable final Object[] args,boolean typeCheckOnly) throws BeansException {
  2. 3
  3. 4 // 第一步: 转换bean name. 在这里传入进来的name可能是别名,也有可能是工厂bean的name,所以在这里进行一个转换
  4. 5 final String beanName = transformedBeanName(name);
  5. 6 Object bean;
  6. 7
  7. Eagerly check singleton cache for manually registered singletons.
  8. 9 // 第二步: 尝试去缓存中获取对象,如果没有获取到就创建bean
  9. 10 Object sharedInstance = getSingleton(beanName);
  10. if (sharedInstance != null && args == ) {
  11. 12 13 判断当前类是否是正在创建中
  12. 14 (isSingletonCurrentlyInCreation(beanName)) {
  13. 15 logger.trace(Returning eagerly cached instance of singleton bean '" + beanName +
  14. 16 ' that is not fully initialized yet - a consequence of a circular reference"17 }
  15. 18 {
  16. 19 logger.trace(Returning cached instance of singleton bean '" + beanName + '2021 }
  17. 22 bean = getObjectForBeanInstance(sharedInstance,name,beanName,2324
  18. 25 26 Fail if we're already creating this bean instance:
  19. 27 We're assumably within a circular reference.
  20. 28 *
  21. 29 * 判断当前的bean是不是多例,如果是这抛出异常
  22. 30 *
  23. 31 * 判断当前这个bean是不是多例bean. 如果配置了@Scope("prototype") 就表示这是一个多例的bean
  24. 32 * spring 只能解决单例对象的setter注入的循环依赖,不能解决构造器注入
  25. 33 *
  26. 34 * 如果是多例的bean,当前正在创建bean,也会抛出异常---这也是循环依赖的问题
  27. 35 */
  28. 36 (isPrototypeCurrentlyInCreation(beanName)) {
  29. 37 throw new BeanCurrentlyInCreationException(beanName);
  30. 39
  31. 40 *
  32. 41 * 下面这段代码是关于子父容器的,只有spring mvc继承自spring,才会有子父容器的问题.
  33. 42 43 Check if bean definition exists in this factory.
  34. 44 beanfactory parentbeanfactory = getParentbeanfactory();
  35. 45 if (parentbeanfactory != null && !containsBeanDefinition(beanName)) {
  36. 46 Not found -> check parent.
  37. 47 String nameToLookup = originalBeanName(name);
  38. 48 (parentbeanfactory instanceof Abstractbeanfactory) {
  39. 49 return ((Abstractbeanfactory) parentbeanfactory).doGetBean(
  40. 50 nameToLookup,requiredType,args,typeCheckOnly);
  41. 5152 else if (args != 53 Delegation to parent with explicit args.
  42. 54 (T) parentbeanfactory.getBean(nameToLookup,args);
  43. 55if (requiredType != 57 No args -> delegate to standard getBean method.
  44. 58 parentbeanfactory.getBean(nameToLookup,requiredType);
  45. 5960 61 (T) parentbeanfactory.getBean(nameToLookup);
  46. 6264
  47. 65 *
  48. 66 * 方法参数typeCheckOnly是用来判断#getBean()方法时,表示是否为仅仅进行类型检查,67 * 如果不仅仅做类型检查,而是创建bean对象,则需要调用#markBeanAsCreated(String name)
  49. 68 *
  50. 69 70 if (!typeCheckOnly) {
  51. 71 markBeanAsCreated(beanName);
  52. 7273
  53. 74 try75 final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
  54. 76 checkMergedBeanDefinition(mbd,1)">77
  55. 78 Guarantee initialization of beans that the current bean depends on.
  56. 79 *
  57. 80 * 现在有两个bean1,bean2,加载的时候调用的是bean1,bean2. 但如果我们想要bean2优先加载,就使用@DependOn注解
  58. 81 * 用来解析带有dependOn注解的类
  59. 82 83 String[] dependsOn = mbd.getDependsOn();
  60. 84 if (dependsOn != 85 (String dep : dependsOn) {
  61. 86 (isDependent(beanName,dep)) {
  62. 87 BeanCreationException(mbd.getResourceDescription(),1)">88 Circular depends-on relationship between '' and '" + dep + 89 }
  63. 90 registerDependentBean(dep,beanName);
  64. 91 92 getBean(dep);
  65. 9394 catch (NoSuchBeanDefinitionException ex) {
  66. 95 96 ' depends on missing bean ',ex);
  67. 9798 }
  68. 99100
  69. 101 Create bean instance.
  70. 102 *
  71. 103 * 第三步: 创建单例bean实例
  72. 104 105 if (mbd.isSingleton()) { 处理单例bean
  73. 106 *
  74. 107 * 这里getSingleton()和上面的getSigleton不一样,上面的是从一级缓存中拿.
  75. 108 * 这个getSingleton()就办了一件事: bean设置为正在创建的状态. 这个状态很重要,如果出现循环依赖,发现bean正在创建,就不会再创建了
  76. 109 110 sharedInstance = getSingleton(beanName,() ->111 112 createBean(beanName,mbd,args);
  77. 113114 (BeansException ex) {
  78. 115 Explicitly remove instance from singleton cache: It might have been put there
  79. 116 eagerly by the creation process,to allow for circular reference resolution.
  80. 117 Also remove any beans that received a temporary reference to the bean.
  81. 118 destroySingleton(beanName);
  82. 119 throw ex;
  83. 120121 });
  84. 122 得到bean实例对象
  85. 123 bean = getObjectForBeanInstance(sharedInstance,mbd);
  86. 124125
  87. 126 if (mbd.isPrototype()) { 处理多例bean
  88. 127 It's a prototype -> create a new instance.
  89. 128 Object prototypeInstance = 129 130 当前正在创建多例bean
  90. 131 beforePrototypeCreation(beanName);
  91. 132 执行创建bean
  92. 133 prototypeInstance =134135 finally136 afterPrototypeCreation(beanName);
  93. 137138 获取bean实例对象
  94. 139 bean = getObjectForBeanInstance(prototypeInstance,1)">140141
  95. 142 else { 处理其他类型的bean
  96. 143 String scopeName = mbd.getScope();
  97. 144 final Scope scope = this.scopes.get(scopeName);
  98. 145 if (scope == 146 new IllegalStateException(No Scope registered for scope name '" + scopeName + );
  99. 147148 149 Object scopedInstance = scope.get(beanName,1)">150 beforePrototypeCreation(beanName);
  100. 151 152 153 }
  101. 154 155 afterPrototypeCreation(beanName);
  102. 156157 });
  103. 158 bean = getObjectForBeanInstance(scopedInstance,1)">159160 (IllegalStateException ex) {
  104. 161 BeanCreationException(beanName,1)">162 Scope '' is not active for the current thread; consider " +
  105. 163 defining a scoped proxy for this bean if you intend to refer to it from a singleton164 ex);
  106. 165166167168 169 cleanupAfterBeanCreationFailure(beanName);
  107. 170 171172 }

 

在这里,首先从缓存中获取bean,看缓存中是否已经存在了

  1. Object sharedInstance = getSingleton(beanName);

然后,如果缓存中已经存在了,那么久直接取出来. 代码如下: 

  1.     if (sharedInstance != null && args == null) {
  2. (logger.isTraceEnabled()) {
  3. 判断当前bean是否是正在创建中(单例bean)
  4. (isSingletonCurrentlyInCreation(beanName)) {
  5. logger.trace(" + beanName +
  6. );
  7. }
  8. {
  9. logger.trace();
  10. }
  11. }
  12. bean = getObjectForBeanInstance(sharedInstance,null);
  13. }

 

如果是空,就说明是第一次创建,执行else的部分

首先,判断是否是正在创建的多例bean,如果是正在创建的多例bean,就抛出异常,

  已经是正在创建了,说明这至少是第二次了,这里处理的是单例bean的循环依赖,不处理多例bean的循环依赖,所以抛出异常

  对应的代码是这一句

  

  1. *
  2. 29 * 判断当前的bean是不是多例,如果是这抛出异常
  3. 30 *
  4. 31 * 判断当前这个bean是不是多例bean. 如果配置了@Scope("prototype") 就表示这是一个多例的bean
  5. 32 * spring 只能解决单例对象的setter注入的循环依赖,1)">38 }

那么,接下来就是首次创建bean. 首次创建的bean有三种情况:

  第一种,这个bean是单例的.

  第二种,这个bean是多例的.

  第三种. 其他类型

对应的代码就是这一块. 有行号,可以和上面一一对应上

  1. if (mbd.isSingleton()) { 处理单例bean
  2. mbd.isPrototype()) { 处理多例bean
  3. else { 处理其他类型的bean
  4. 166 }

 

我们的重点研究对象是单例bean. 所以,重点看单例bean的实现

  1. if (mbd.isSingleton()) { // 处理单例bean
  2. 110 sharedInstance = getSingleton(beanName,() -> {
  3. 111 try {
  4. 112 return createBean(beanName,args);
  5. 113 }
  6. 114 catch (BeansException ex) {
  7. 115 // Explicitly remove instance from singleton cache: It might have been put there
  8. 116 // eagerly by the creation process,to allow for circular reference resolution.
  9. 117 // Also remove any beans that received a temporary reference to the bean.
  10. 118 destroySingleton(beanName);
  11. 119 throw ex;
  12. 120 }
  13. });
  14. 123 bean =124 }

 

这里的重点是调用了getSingleton(beanName,FactoryObject); FactoryObject是一个接口. 定义了一个钩子方法getObject(). 

这个接口在这里这是进行了定义,并不会执行. 什么时候执行呢? 后面调用的时候执行. 

下面来看看getSingleton()方法,钩子方法也是在这里被调用的.

  1. public Object getSingleton(String beanName,ObjectFactory<?> singletonFactory) {
  2. 2 Assert.notNull(beanName,Bean name must not be null3 synchronized (.singletonObjects) {
  3. 4 // 第一步: 从一级缓存中获取单例对象
  4. 5 Object singletonObject = this.singletonObjects.(beanName);
  5. 6 if (singletonObject == 7 .singletonsCurrentlyInDestruction) {
  6. 8 BeanCreationNotAllowedException(beanName,1)">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!)1112 (logger.isDebugEnabled()) {
  7. 13 logger.debug(Creating shared instance of singleton bean '1415 // 第二步: 将bean添加到singletonsCurrentlyInCreation中,表示bean正在创建
  8. 16 beforeSingletonCreation(beanName);
  9. 17 boolean newSingleton = false18 boolean recordSuppressedExceptions = (this.suppressedExceptions == 19 (recordSuppressedExceptions) {
  10. 20 this.suppressedExceptions = new LinkedHashSet<>();
  11. 22 23 // 第三步: 这里调用getObject()钩子方法,就会回调匿名函数,调用singletonFactory的createBean()
  12. 24 singletonObject = singletonFactory.getObject();
  13. 25 newSingleton = true2627 28 Has the singleton object implicitly appeared in the meantime ->
  14. 29 if yes,proceed with it since the exception indicates that state.
  15. 30 singletonObject = (beanName);
  16. 31 32 3335 (BeanCreationException ex) {
  17. 36 37 for (Exception suppressedException : .suppressedExceptions) {
  18. ex.addRelatedCause(suppressedException);
  19. 41 43 44 45 4647 afterSingletonCreation(beanName);
  20. 4849 (newSingleton) {
  21. addSingleton(beanName,singletonObject);
  22. 5253 singletonObject;
  23. 5455 }

 

这里是调用getBean().

第一步: 去一级缓存中取成熟的单例bean. 如果拿到了,就直接返回. 如果没拿到. 那么执行创建. 

第二步: 在创建之前,先把这个bean放入到正在创建的单例bean集合中. 标记这个bean正在创建中

第三步: 就是调用钩子方法getObject()了. 这个方法方法体是在上面定义的. 其内容是去创建实例

  1.             sharedInstance = getSingleton(beanName,1)"> {
  2. {
  3. // 这里定义了一个钩子函数. 此时只是定义,并不执行. 在真正需要创建bean的地方才会执行
  4. return createBean(beanName,args);
  5. }
  6. (BeansException ex) {
  7. Explicitly remove instance from singleton cache: It might have been put there
  8. Also remove any beans that received a temporary reference to the bean.
  9. destroySingleton(beanName);
  10. ex;
  11. }
  12. });

 

这里的代码逻辑是完成了创建之前的逻辑

2.3 创建bean 

下面看看创建bean的过程

  1. 1 protected Object doCreateBean(final String beanName,final RootBeanDefinition mbd,final @Nullable Object[] args)
  2. 2 throws BeanCreationException {
  3. 3
  4. 4 Instantiate the bean.
  5. 5 BeanWrapper instanceWrapper = ;
  6. 6 (mbd.isSingleton()) {
  7. 7 instanceWrapper = .factorybeanInstanceCache.remove(beanName);
  8. 8 }
  9. 9 if (instanceWrapper == ) {
  10. 10 *
  11. 11 * 第一步: 实例化
  12. 12 * 这里面的调用链非常深,后面再看
  13. 13 * bean实例化有两种方式
  14. 14 * 1. 使用反射: 使用反射也有两种方式, 15 * a. 通过无参构造函数 (默认的方式)
  15. 16 * beanDefinition中可以得到beanClass,1)"> 17 * ClassName = BeanDefinition.beanClass
  16. 18 * Class clazz = Class.forName(ClassName);
  17. 19 * clazz.newInstance();
  18. 20 * 这样就可以实例化bean了
  19. 21 *
  20. 22 * b. 通过有参函数.
  21. 23 * ClassName = BeanDefinition.beanClass
  22. 24 25 * Constractor con = class.getConstractor(args....)
  23. 26 * con.newInstance();
  24. 27 28 * 2. 使用工厂
  25. 29 * 我们使用@Bean的方式,就是使用的工厂模式,自己控制实例化过程
  26. 30 31 */
  27. 32 instanceWrapper = createBeanInstance(beanName,args);
  28. 33 34 这里使用了装饰器的设计模式
  29. 35 final Object bean = instanceWrapper.getWrappedInstance();
  30. 36 Class<?> beanType = instanceWrapper.getWrappedClass();
  31. 37 if (beanType != NullBean.class 38 mbd.resolvedTargetType = beanType;
  32. 39 40
  33. 41 Allow post-processors to modify the merged bean definition.
  34. 42 允许后置处理器修改已经合并的beanDefinition
  35. 43 synchronized (mbd.postProcessingLock) {
  36. 44 mbd.postProcessed) {
  37. 45 {
  38. 46 applyMergedBeanDefinitionPostProcessors(mbd,beanType,beanName);
  39. 47 }
  40. 48 (Throwable ex) {
  41. 49 50 Post-processing of merged bean definition Failed 51 52 mbd.postProcessed = 53 }
  42. 54 55
  43. 56 57 * 缓存单例bean到三级缓存中,以防止循环依赖
  44. 58 * 判断是否是早期引用的bean,如果是,则允许提前暴露引用
  45. 59      *
  46. 60 * 判断是否能够早起暴露的条件
  47. 61 * 1. 是单例
  48. 62 * 2. 允许循环依赖
  49. 63 * 3. 正在创建的bean
  50. 64 65 boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
  51. 66 isSingletonCurrentlyInCreation(beanName));
  52. 67 (earlySingletonExposure) {
  53. 68 (logger.isTraceEnabled()) {
  54. 69 logger.trace(Eagerly caching bean '" + beanName +
  55. 70 ' to allow for resolving potential circular references);
  56. 71 72 把我们的早期对象包装成一个singletonFactory对象,该对象提供了getObject()方法,把静态的bean放到三级缓存中去了.
  57. 73 addSingletonFactory(beanName,1)"> getEarlyBeanReference(beanName,bean));
  58. 74 75
  59. 76 Initialize the bean instance.
  60. 77 Object exposedObject = bean;
  61. 78 79 第二步:填充属性,给属性赋值(调用set方法) 这里也是调用的后置处理器
  62. 80 populateBean(beanName,instanceWrapper);
  63. 81 // 第三步: 初始化.
  64. 82 exposedObject = initializeBean(beanName,exposedObject,mbd);
  65. 83 84 85 if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
  66. 86 (BeanCreationException) ex;
  67. 87 88 89 BeanCreationException(
  68. 90 mbd.getResourceDescription(),1)">Initialization of bean Failed 91 92 93
  69. 94 95 * 初始化完成以后,判断是否是早期的对象
  70. 96 * 是循环依赖. 才会走进这里来
  71. 97 98 99 去缓存中获取到我们的对象 由于传递的allowEarlyReference是false,要求只能在一级二级缓存中取
  72. 100 正常的普通的bean(不存在循环依赖的bean) 创建的过程中,不会把三级缓存提升到二级缓存中.
  73. 101 Object earlySingletonReference = getSingleton(beanName,1)">102 if (earlySingletonReference != 103 if (exposedObject == bean) {
  74. 104 exposedObject = earlySingletonReference;
  75. 105 106 this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
  76. 107 String[] dependentBeans = getDependentBeans(beanName);
  77. 108 Set<String> actualDependentBeans = (dependentBeans.length);
  78. 109 (String dependentBean : dependentBeans) {
  79. 110 removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
  80. 111 actualDependentBeans.add(dependentBean);
  81. 112 }
  82. 113 }
  83. 114 actualDependentBeans.isEmpty()) {
  84. 115 BeanCurrentlyInCreationException(beanName,1)">116 Bean with name '' has been injected into other beans [" +
  85. 117 StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
  86. 118 ] in its raw version as part of a circular reference,but has eventually been 119 wrapped. This means that said other beans do not use the final version of the 120 bean. This is often the result of over-eager type matching - consider using 121 'getBeanNamesForType' with the 'allowEagerInit' flag turned off,for example.122 123 124 125 126
  87. 127 Register bean as disposable.
  88. 128 129 registerDisposableBeanIfNecessary(beanName,bean,1)">130 131 (BeanDefinitionValidationException ex) {
  89. 132 133 mbd.getResourceDescription(),1)">Invalid destruction signature134 135
  90. 136 exposedObject;
  91. 137 }

 

首先,实例化bean,实例化的方式有两种. 一种是通过反射,另一种是通过动态

  1. 1         2 3 4 5 * 1. 使用反射: 使用反射也有两种方式,1)"> 6 7 8 9 10 11 12 13 14 15 16 17 18 19 * 2. 使用工厂
  2. 20 21 22 23 instanceWrapper = createBeanInstance(beanName,args);

 

判断是否是早期暴露的bean. 满足早期暴露的bean的三个条件是

1. 是单例的

2. 允许循环依赖

3. bean已经是处在正在创建中的行列了.

  1.      判断是否能够早起暴露的条件
  2. * 1. 是单例
  3. * 2. 允许循环依赖
  4. * 3. 正在创建的bean
  5. */
  6. boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
  7. isSingletonCurrentlyInCreation(beanName));

 

创建bean的第二步: 属性赋值

  1. // 第二步:填充属性,给属性赋值(调用set方法) 这里也是调用的后置处理器
  2. populateBean(beanName,instanceWrapper);

在这里会判断,是否带有@Autowired的属性. 分为两种一种是Name,一种是Type

  1. @SuppressWarnings(deprecation") for postProcessPropertyValues
  2. protected populateBean(String beanName,RootBeanDefinition mbd,@Nullable BeanWrapper bw) {
  3. if (bw == ) {
  4. (mbd.hasPropertyValues()) {
  5. BeanCreationException(
  6. mbd.getResourceDescription(),1)">Cannot apply property values to null instance);
  7. }
  8. {
  9. Skip property population phase for null instance.
  10. ;
  11. }
  12. }
  13. Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
  14. state of the bean before properties are set. This can be used,for example,1)"> to support styles of field injection.
  15. if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
  16. (BeanPostProcessor bp : getBeanPostProcessors()) {
  17. (bp instanceof InstantiationAwareBeanPostProcessor) {
  18. InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
  19. ibp.postProcessAfterInstantiation(bw.getWrappedInstance(),beanName)) {
  20. ;
  21. }
  22. }
  23. }
  24. }
  25. PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : );
  26. 判断属性是否有Autowired注解
  27. int resolvedAutowireMode = mbd.getResolvedAutowireMode();
  28. Autowired是根据名字或者根据类型
  29. if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
  30. MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
  31. // Add property values based on autowire by name if applicable.
  32. if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
  33. autowireByName(beanName,bw,newPvs);
  34. }
  35. // Add property values based on autowire by type if applicable.
  36. if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
  37. autowireByType(beanName,newPvs);
  38. }
  39. pvs = newPvs;
  40. }
  41.  
  42. ......
  43. }

 

如果按照名字注入

  1. 1 autowireByName(
  2. String beanName,AbstractBeanDefinition mbd,BeanWrapper bw,MutablePropertyValues pvs) {
  3. 3
  4. 4 String[] propertyNames = unsatisfiedNonSimpleProperties(mbd,bw);
  5. 5 (String propertyName : propertyNames) {
  6. 6 (containsBean(propertyName)) {
  7. 7 // 调用getBean
  8. 8 Object bean = getBean(propertyName);
  9. pvs.add(propertyName,bean);
  10. registerDependentBean(propertyName,1)">11 12 logger.trace(Added autowiring by name from bean name '13 ' via property '" + propertyName + ' to bean named '17 18 logger.trace(Not autowiring property '' of bean '19 ' by name: no matching bean found22 23 }

 

会再次调用getBean方法. 构建bean. 这是就有可能出现循环依赖了. 

按类型注入也是一样的. 

只是解析bean的方式不同.

 

创建bean的第三步: 初始化

  1. // 第三步: 初始化.
  2. exposedObject = initializeBean(beanName,mbd);

在初始化bean的时候,会调用很多的aware. 还会调用init-method方法. 以及bean的后置处理器.

 

第四步:删除实例化和静态方法在缓存中的数据

  1. *
  2. * 初始化完成以后,判断是否是早期的对象
  3. * 是循环依赖. 才会走进这里来
  4. */
  5. (earlySingletonExposure) {
  6. Object earlySingletonReference = getSingleton(beanName,1)">);
  7. ) {
  8. bean) {
  9. exposedObject = earlySingletonReference;
  10. }
  11. hasDependentBean(beanName)) {
  12. String[] dependentBeans = getDependentBeans(beanName);
  13. Set<String> actualDependentBeans = (dependentBeans.length);
  14. (String dependentBean : dependentBeans) {
  15. removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
  16. actualDependentBeans.add(dependentBean);
  17. }
  18. }
  19. actualDependentBeans.isEmpty()) {
  20. " +
  21. StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
  22. " +
  23. );
  24. }
  25. }
  26. }
  27. }

 

  1. removeSingletonIfCreatedForTypeCheckOnly调用方法,删除缓存.

这既是getBean()整个的过程. 中间还有很多细节,没有往里面深入的看,因为spring代码非常的深,看的太深就忘了我们的目标了. 结合之前手写的spring循环依赖的思想看,还是可以看得懂的. 

 

 

三. 接下来有几个问题

问题1: 为什么需要二级缓存和三级缓存?

一级缓存: 用来存储完整的bean

二级缓存: 用来存储早期的,纯净的bean,也就是没有注入属性的bean

三级缓存: 存的是函数的接口,主要目的是为了解耦

 二级缓存 和三级缓存 结合起来,解决了循环依赖下的AOP动态代理的问题

问题2:有没有解决构造函数的循环依赖

答案是没有. 因为构造函数是在实例化的时候构建的. 这个时候bean都还没有创建,所以没有办法处理循环依赖.如果出现构造函数的循环依赖,是会直接报错的..

 

问题3:有没有解决多例下的循环依赖

也是没有的,因为我们会判断,如果是多例,那么会抛出异常

  1. 1 /**
  2. 2 * 第二步: 判断当前bean是否是正在创建中的多例bean,如果是就抛出异常
  3. 3 *
  4. 4 * 2. 判断当前这个bean是不是多例bean. 如果配置了@Scope("prototype") 就表示这是一个多例的bean
  5. 5 * spring 只能解决单例对象的setter注入的循环依赖,不能解决构造器注入
  6. 6 *
  7. 7 * 如果是多例的bean,也会抛出异常---这也是循环依赖的问题
  8. 8 */
  9. 9 (isPrototypeCurrentlyInCreation(beanName)) {
  10. 10 BeanCurrentlyInCreationException(beanName);
  11. 11 }

 

猜你在找的Spring相关文章