Spring DI 源码分析&时序图 非原创- 2020-12-26 23:22- spring: spring DI 时序图
—-

依赖注入发生的时间

当 Spring IOC 容器完成了 Bean 定义资源的定位、载入和解析注册以后,IOC 容器中已经管理类 Bean定义的相关数据,但是此时 IOC 容器还没有对所管理的 Bean 进行依赖注入,依赖注入在以下两种情况发生:
1)、用户第一次调用 getBean()方法时,IOC 容器触发依赖注入。
2)、当用户在配置文件中将元素配置了 lazy-init=false 属性,即让容器在解析注册 Bean 定义时进行预实例化,触发依赖注入。

BeanFactory 接口定义了 Spring IOC 容器的基本功能规范,是 Spring IOC 容器所应遵守的最底层和最基本的编程规范。BeanFactory 接口中定义了几个 getBean()方法,就是用户向 IOC 容器索取管理的Bean 的方法,我们通过分析其子类的具体实现,理解 Spring IOC 容器在用户索取 Bean 时如何完成依赖注入。
image.png
在 BeanFactory 中我们可以看到 getBean(String…)方法,但它具体实现在 AbstractBeanFactory 中。

源码分析

寻找获取 Bean 的入口

AbstractBeanFactory 的 getBean()相关方法的源码如下:

  1. @Override
  2. public Object getBean(String name) throws BeansException {
  3. //doGetBean才是真正向IoC容器获取被管理Bean的过程
  4. return doGetBean(name, null, null, false);
  5. }
  6. //获取IOC容器中指定名称和类型的Bean
  7. @Override
  8. public <T> T getBean(String name, @Nullable Class<T> requiredType) throws BeansException {
  9. //doGetBean才是真正向IoC容器获取被管理Bean的过程
  10. return doGetBean(name, requiredType, null, false);
  11. }
  12. //获取IOC容器中指定名称和参数的Bean
  13. @Override
  14. public Object getBean(String name, Object... args) throws BeansException {
  15. //doGetBean才是真正向IoC容器获取被管理Bean的过程
  16. return doGetBean(name, null, args, false);
  17. }
  18. //获取IOC容器中指定名称、类型和参数的Bean
  19. public <T> T getBean(String name, @Nullable Class<T> requiredType, @Nullable Object... args)
  20. throws BeansException {
  21. //doGetBean才是真正向IoC容器获取被管理Bean的过程
  22. return doGetBean(name, requiredType, args, false);
  23. }
  24. @SuppressWarnings("unchecked")
  25. //真正实现向IOC容器获取Bean的功能,也是触发依赖注入功能的地方
  26. protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
  27. @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
  28. //根据指定的名称获取被管理Bean的名称,剥离指定名称中对容器的相关依赖
  29. //如果指定的是别名,将别名转换为规范的Bean名称
  30. final String beanName = transformedBeanName(name);
  31. Object bean;
  32. // Eagerly check singleton cache for manually registered singletons.
  33. //先从缓存中取是否已经有被创建过的单态类型的Bean
  34. //对于单例模式的Bean整个IOC容器中只创建一次,不需要重复创建
  35. Object sharedInstance = getSingleton(beanName);
  36. //IOC容器创建单例模式Bean实例对象
  37. if (sharedInstance != null && args == null) {
  38. if (logger.isDebugEnabled()) {
  39. //如果指定名称的Bean在容器中已有单例模式的Bean被创建
  40. //直接返回已经创建的Bean
  41. if (isSingletonCurrentlyInCreation(beanName)) {
  42. logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
  43. "' that is not fully initialized yet - a consequence of a circular reference");
  44. }
  45. else {
  46. logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
  47. }
  48. }
  49. //获取给定Bean的实例对象,主要是完成FactoryBean的相关处理
  50. //注意:BeanFactory是管理容器中Bean的工厂,而FactoryBean是
  51. //创建创建对象的工厂Bean,两者之间有区别
  52. bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
  53. }
  54. else {
  55. // Fail if we're already creating this bean instance:
  56. // We're assumably within a circular reference.
  57. //缓存没有正在创建的单例模式Bean
  58. //缓存中已经有已经创建的原型模式Bean
  59. //但是由于循环引用的问题导致实例化对象失败
  60. if (isPrototypeCurrentlyInCreation(beanName)) {
  61. throw new BeanCurrentlyInCreationException(beanName);
  62. }
  63. // Check if bean definition exists in this factory.
  64. //对IOC容器中是否存在指定名称的BeanDefinition进行检查,首先检查是否
  65. //能在当前的BeanFactory中获取的所需要的Bean,如果不能则委托当前容器
  66. //的父级容器去查找,如果还是找不到则沿着容器的继承体系向父级容器查找
  67. BeanFactory parentBeanFactory = getParentBeanFactory();
  68. //当前容器的父级容器存在,且当前容器中不存在指定名称的Bean
  69. if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
  70. // Not found -> check parent.
  71. //解析指定Bean名称的原始名称
  72. String nameToLookup = originalBeanName(name);
  73. if (parentBeanFactory instanceof AbstractBeanFactory) {
  74. return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
  75. nameToLookup, requiredType, args, typeCheckOnly);
  76. }
  77. else if (args != null) {
  78. // Delegation to parent with explicit args.
  79. //委派父级容器根据指定名称和显式的参数查找
  80. return (T) parentBeanFactory.getBean(nameToLookup, args);
  81. }
  82. else {
  83. // No args -> delegate to standard getBean method.
  84. //委派父级容器根据指定名称和类型查找
  85. return parentBeanFactory.getBean(nameToLookup, requiredType);
  86. }
  87. }
  88. //创建的Bean是否需要进行类型验证,一般不需要
  89. if (!typeCheckOnly) {
  90. //向容器标记指定的Bean已经被创建
  91. markBeanAsCreated(beanName);
  92. }
  93. try {
  94. //根据指定Bean名称获取其父级的Bean定义
  95. //主要解决Bean继承时子类合并父类公共属性问题
  96. final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
  97. checkMergedBeanDefinition(mbd, beanName, args);
  98. // Guarantee initialization of beans that the current bean depends on.
  99. //获取当前Bean所有依赖Bean的名称
  100. String[] dependsOn = mbd.getDependsOn();
  101. //如果当前Bean有依赖Bean
  102. if (dependsOn != null) {
  103. for (String dep : dependsOn) {
  104. if (isDependent(beanName, dep)) {
  105. throw new BeanCreationException(mbd.getResourceDescription(), beanName,
  106. "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
  107. }
  108. //递归调用getBean方法,获取当前Bean的依赖Bean
  109. registerDependentBean(dep, beanName);
  110. //把被依赖Bean注册给当前依赖的Bean
  111. getBean(dep);
  112. }
  113. }
  114. // Create bean instance.
  115. //创建单例模式Bean的实例对象
  116. if (mbd.isSingleton()) {
  117. //这里使用了一个匿名内部类,创建Bean实例对象,并且注册给所依赖的对象
  118. sharedInstance = getSingleton(beanName, () -> {
  119. try {
  120. //创建一个指定Bean实例对象,如果有父级继承,则合并子类和父类的定义
  121. return createBean(beanName, mbd, args);
  122. }
  123. catch (BeansException ex) {
  124. // Explicitly remove instance from singleton cache: It might have been put there
  125. // eagerly by the creation process, to allow for circular reference resolution.
  126. // Also remove any beans that received a temporary reference to the bean.
  127. //显式地从容器单例模式Bean缓存中清除实例对象
  128. destroySingleton(beanName);
  129. throw ex;
  130. }
  131. });
  132. //获取给定Bean的实例对象
  133. bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
  134. }
  135. //IOC容器创建原型模式Bean实例对象
  136. else if (mbd.isPrototype()) {
  137. // It's a prototype -> create a new instance.
  138. //原型模式(Prototype)是每次都会创建一个新的对象
  139. Object prototypeInstance = null;
  140. try {
  141. //回调beforePrototypeCreation方法,默认的功能是注册当前创建的原型对象
  142. beforePrototypeCreation(beanName);
  143. //创建指定Bean对象实例
  144. prototypeInstance = createBean(beanName, mbd, args);
  145. }
  146. finally {
  147. //回调afterPrototypeCreation方法,默认的功能告诉IOC容器指定Bean的原型对象不再创建
  148. afterPrototypeCreation(beanName);
  149. }
  150. //获取给定Bean的实例对象
  151. bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
  152. }
  153. //要创建的Bean既不是单例模式,也不是原型模式,则根据Bean定义资源中
  154. //配置的生命周期范围,选择实例化Bean的合适方法,这种在Web应用程序中
  155. //比较常用,如:request、session、application等生命周期
  156. else {
  157. String scopeName = mbd.getScope();
  158. final Scope scope = this.scopes.get(scopeName);
  159. //Bean定义资源中没有配置生命周期范围,则Bean定义不合法
  160. if (scope == null) {
  161. throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
  162. }
  163. try {
  164. //这里又使用了一个匿名内部类,获取一个指定生命周期范围的实例
  165. Object scopedInstance = scope.get(beanName, () -> {
  166. beforePrototypeCreation(beanName);
  167. try {
  168. return createBean(beanName, mbd, args);
  169. }
  170. finally {
  171. afterPrototypeCreation(beanName);
  172. }
  173. });
  174. //获取给定Bean的实例对象
  175. bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
  176. }
  177. catch (IllegalStateException ex) {
  178. throw new BeanCreationException(beanName,
  179. "Scope '" + scopeName + "' is not active for the current thread; consider " +
  180. "defining a scoped proxy for this bean if you intend to refer to it from a singleton",
  181. ex);
  182. }
  183. }
  184. }
  185. catch (BeansException ex) {
  186. cleanupAfterBeanCreationFailure(beanName);
  187. throw ex;
  188. }
  189. }
  190. // Check if required type matches the type of the actual bean instance.
  191. //对创建的Bean实例对象进行类型检查
  192. if (requiredType != null && !requiredType.isInstance(bean)) {
  193. try {
  194. T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
  195. if (convertedBean == null) {
  196. throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
  197. }
  198. return convertedBean;
  199. }
  200. catch (TypeMismatchException ex) {
  201. if (logger.isDebugEnabled()) {
  202. logger.debug("Failed to convert bean '" + name + "' to required type '" +
  203. ClassUtils.getQualifiedName(requiredType) + "'", ex);
  204. }
  205. throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
  206. }
  207. }
  208. return (T) bean;
  209. }

通过上面对向 IOC 容器获取 Bean 方法的分析,我们可以看到在 Spring 中,如果 Bean 定义的单例模式(Singleton),则容器在创建之前先从缓存中查找,以确保整个容器中只存在一个实例对象。如果 Bean定义的是原型模式(Prototype),则容器每次都会创建一个新的实例对象。除此之外,Bean 定义还可以扩展为指定其生命周期范围。
上面的源码只是定义了根据 Bean 定义的模式,采取的不同创建 Bean 实例对象的策略,具体的 Bean实例 对象的创 建过程 由实现了 ObjectFactory 接口 的匿名内 部类的 createBean()方法 完成,ObjectFactory 使 用 委 派 模 式 ,具体的 Bean 实 例 创 建 过 程 交 由 其 实 现 类AbstractAutowireCapableBeanFactory 完成,我们继续分析AbstractAutowireCapableBeanFactory的 createBean()方法的源码,理解其创建 Bean 实例的具体实现过程。

开始实例化

AbstractAutowireCapableBeanFactory 类实现了 ObjectFactory 接口,创建容器指定的 Bean 实例对象,同时还对创建的 Bean 实例对象进行初始化处理。其创建 Bean 实例对象的方法源码如下:

  1. //创建Bean实例对象
  2. @Override
  3. protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
  4. throws BeanCreationException {
  5. if (logger.isDebugEnabled()) {
  6. logger.debug("Creating instance of bean '" + beanName + "'");
  7. }
  8. RootBeanDefinition mbdToUse = mbd;
  9. //判断需要创建的Bean是否可以实例化,即是否可以通过当前的类加载器加载
  10. Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
  11. if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
  12. mbdToUse = new RootBeanDefinition(mbd);
  13. mbdToUse.setBeanClass(resolvedClass);
  14. }
  15. // Prepare method overrides.
  16. //校验和准备Bean中的方法覆盖
  17. try {
  18. mbdToUse.prepareMethodOverrides();
  19. }
  20. catch (BeanDefinitionValidationException ex) {
  21. throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
  22. beanName, "Validation of method overrides failed", ex);
  23. }
  24. try {
  25. // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
  26. //如果Bean配置了初始化前和初始化后的处理器,则试图返回一个需要创建Bean的代理对象
  27. Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
  28. if (bean != null) {
  29. return bean;
  30. }
  31. }
  32. catch (Throwable ex) {
  33. throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
  34. "BeanPostProcessor before instantiation of bean failed", ex);
  35. }
  36. try {
  37. //创建Bean的入口
  38. Object beanInstance = doCreateBean(beanName, mbdToUse, args);
  39. if (logger.isDebugEnabled()) {
  40. logger.debug("Finished creating instance of bean '" + beanName + "'");
  41. }
  42. return beanInstance;
  43. }
  44. catch (BeanCreationException ex) {
  45. // A previously detected exception with proper bean creation context already...
  46. throw ex;
  47. }
  48. catch (ImplicitlyAppearedSingletonException ex) {
  49. // An IllegalStateException to be communicated up to DefaultSingletonBeanRegistry...
  50. throw ex;
  51. }
  52. catch (Throwable ex) {
  53. throw new BeanCreationException(
  54. mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
  55. }
  56. }
  57. //真正创建Bean的方法
  58. protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
  59. throws BeanCreationException {
  60. // Instantiate the bean.
  61. //封装被创建的Bean对象
  62. BeanWrapper instanceWrapper = null;
  63. if (mbd.isSingleton()) {
  64. instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
  65. }
  66. if (instanceWrapper == null) {
  67. instanceWrapper = createBeanInstance(beanName, mbd, args);
  68. }
  69. final Object bean = instanceWrapper.getWrappedInstance();
  70. //获取实例化对象的类型
  71. Class<?> beanType = instanceWrapper.getWrappedClass();
  72. if (beanType != NullBean.class) {
  73. mbd.resolvedTargetType = beanType;
  74. }
  75. // Allow post-processors to modify the merged bean definition.
  76. //调用PostProcessor后置处理器
  77. synchronized (mbd.postProcessingLock) {
  78. if (!mbd.postProcessed) {
  79. try {
  80. applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
  81. }
  82. catch (Throwable ex) {
  83. throw new BeanCreationException(mbd.getResourceDescription(), beanName,
  84. "Post-processing of merged bean definition failed", ex);
  85. }
  86. mbd.postProcessed = true;
  87. }
  88. }
  89. // Eagerly cache singletons to be able to resolve circular references
  90. // even when triggered by lifecycle interfaces like BeanFactoryAware.
  91. //向容器中缓存单例模式的Bean对象,以防循环引用
  92. boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
  93. isSingletonCurrentlyInCreation(beanName));
  94. if (earlySingletonExposure) {
  95. if (logger.isDebugEnabled()) {
  96. logger.debug("Eagerly caching bean '" + beanName +
  97. "' to allow for resolving potential circular references");
  98. }
  99. //这里是一个匿名内部类,为了防止循环引用,尽早持有对象的引用
  100. addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
  101. }
  102. // Initialize the bean instance.
  103. //Bean对象的初始化,依赖注入在此触发
  104. //这个exposedObject在初始化完成之后返回作为依赖注入完成后的Bean
  105. Object exposedObject = bean;
  106. try {
  107. //将Bean实例对象封装,并且Bean定义中配置的属性值赋值给实例对象
  108. populateBean(beanName, mbd, instanceWrapper);
  109. //初始化Bean对象
  110. exposedObject = initializeBean(beanName, exposedObject, mbd);
  111. }
  112. catch (Throwable ex) {
  113. if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
  114. throw (BeanCreationException) ex;
  115. }
  116. else {
  117. throw new BeanCreationException(
  118. mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
  119. }
  120. }
  121. if (earlySingletonExposure) {
  122. //获取指定名称的已注册的单例模式Bean对象
  123. Object earlySingletonReference = getSingleton(beanName, false);
  124. if (earlySingletonReference != null) {
  125. //根据名称获取的已注册的Bean和正在实例化的Bean是同一个
  126. if (exposedObject == bean) {
  127. //当前实例化的Bean初始化完成
  128. exposedObject = earlySingletonReference;
  129. }
  130. //当前Bean依赖其他Bean,并且当发生循环引用时不允许新创建实例对象
  131. else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
  132. String[] dependentBeans = getDependentBeans(beanName);
  133. Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
  134. //获取当前Bean所依赖的其他Bean
  135. for (String dependentBean : dependentBeans) {
  136. //对依赖Bean进行类型检查
  137. if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
  138. actualDependentBeans.add(dependentBean);
  139. }
  140. }
  141. if (!actualDependentBeans.isEmpty()) {
  142. throw new BeanCurrentlyInCreationException(beanName,
  143. "Bean with name '" + beanName + "' has been injected into other beans [" +
  144. StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
  145. "] in its raw version as part of a circular reference, but has eventually been " +
  146. "wrapped. This means that said other beans do not use the final version of the " +
  147. "bean. This is often the result of over-eager type matching - consider using " +
  148. "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
  149. }
  150. }
  151. }
  152. }
  153. // Register bean as disposable.
  154. //注册完成依赖注入的Bean
  155. try {
  156. registerDisposableBeanIfNecessary(beanName, bean, mbd);
  157. }
  158. catch (BeanDefinitionValidationException ex) {
  159. throw new BeanCreationException(
  160. mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
  161. }
  162. return exposedObject;
  163. }