1. Spring IoC 容器初始化主题流程

1.1 Spring IoC容器体系

  1. 容器是一组组件和过程的合集,包括BeanFactory、单例池、BeanPostProcessor等
  2. 用于存放和管理实例化对象的**Map**集合其实是容器中的单例池

    BeanFactory

    BeanFactory注释第一句话:
    _The root interface for accessing a Spring bean container._
    image.png

  3. 获取Bean对象 Object getBean

  4. 获取Bean的提供者 <T> ObjectProvider<T> getBeanProvider
  5. 判断Factory是否有Beanboolean containsBean
  6. 判断是否为单例Beanboolean isSingleton
  7. 判断是否为原型Beanboolean isPrototype
  8. 判断是否匹配类型boolean isTypeMatch
  9. 获取Bean类型Class<?> getType
  10. 获取别名String[] getAliases
  11. FactoryBean 定位符:String _FACTORY_BEAN_PREFIX _= "&";
    • Spring的Bean分两种:普通BeanFactoryBean,Spring会通过"&"来定位区分FactoryBean

      1.2 Bean 生命周期关键时间点

      | 关键点 | 触发代码 | | —- | —- | | 构造器执行、初始化方法调用 | refresh#finishBeanFactoryInitialization(beanFactory) | | BeanFactoryPostProcessor 初始化 | refresh#invokeBeanFactoryPostProcessors(beanFactory) | | BeanFactoryPostProcessor ⽅法调⽤ | refresh#invokeBeanFactoryPostProcessors(beanFactory) | | BeanPostProcessor 初始化 | refresh#registerBeanPostProcessors(beanFactory) | | BeanPostProcessor ⽅法调⽤ | refresh#finishBeanFactoryInitialization(beanFactory) |

SpringBean的生命周期

  1. Bean 容器找到配置文件中 Spring Bean 的定义。
  2. Bean 容器利用 Java Reflection API 创建一个 Bean 的实例。
  3. 如果涉及到一些属性值 利用 set()方法设置一些属性值。
  4. 如果 Bean 实现了 BeanNameAware 接口,调用 setBeanName()方法,传入 Bean 的名字。
  5. 如果 Bean 实现了 BeanClassLoaderAware 接口,调用 setBeanClassLoader()方法,传入 ClassLoader对象的实例。
  6. 如果 Bean 实现了 BeanFactoryAware 接口,调用 setBeanFactory()方法,传入 BeanFactory对象的实例。
  7. 与上面的类似,如果实现了其他 .*Aware接口,就调用相应的方法。
  8. 如果有和加载这个 Bean 的 Spring 容器相关的 BeanPostProcessor 对象,执行postProcessBeforeInitialization() 方法
  9. 如果 Bean 实现了InitializingBean接口,执行afterPropertiesSet()方法。
  10. 如果 Bean 在配置文件中的定义包含_ init-method_ 属性,执行指定的方法。
  11. 如果有和加载这个 Bean 的 Spring 容器相关的 BeanPostProcessor 对象,执行postProcessAfterInitialization() 方法
  12. 当要销毁 Bean 的时候,如果 Bean 实现了 DisposableBean 接口,执行 destroy()方法。
  13. 当要销毁 Bean 的时候,如果 Bean 在配置文件中的定义包含 destroy-method 属性,执行指定的方法。

Spring 源码 - 图2

1.3 容器初始化主流程

refersh() 方法

  1. /**
  2. * Load or refresh the persistent representation of the configuration, which
  3. * might be from Java-based configuration, an XML file, a properties file, a
  4. * relational database schema, or some other format.
  5. * <p>As this is a startup method, it should destroy already created singletons
  6. * if it fails, to avoid dangling resources. In other words, after invocation
  7. * of this method, either all or no singletons at all should be instantiated.
  8. * @throws BeansException if the bean factory could not be initialized
  9. * @throws IllegalStateException if already initialized and multiple refresh
  10. * attempts are not supported
  11. */
  12. @Override
  13. public void refresh() throws BeansException, IllegalStateException {
  14. synchronized (this.startupShutdownMonitor) {
  15. // Prepare this context for refreshing.
  16. /*
  17. * 刷新前的预处理
  18. * 设置spring容器的启动时间
  19. * 开启活跃状态,撤销关闭时间
  20. * 验证环境信息里一些必须属性
  21. */
  22. prepareRefresh();
  23. // Tell the subclass to refresh the internal bean factory.
  24. /*
  25. * 获取BeanFactory; 默认实现是DefaultListableBeanFactory
  26. * 加载BeanDefinition并注册到BeanDefinitionRegistry
  27. */
  28. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
  29. // Prepare the bean factory for use in this context.
  30. /*
  31. * BeanFactory的准备工作,比如context的类加载器等
  32. */
  33. prepareBeanFactory(beanFactory);
  34. try {
  35. // Allows post-processing of the bean factory in context subclasses.
  36. postProcessBeanFactory(beanFactory);
  37. // Invoke factory processors registered as beans in the context.
  38. // 实例化实现了BeanFactoryPostProcessor接口的Bean,并调用接口方法
  39. /*
  40. * 在此之前,所有bean definition都已加载,但还没有实例化任何bean。
  41. * BeanFactoryPostProcessor是针对BeanFactory的扩展,
  42. * 主要用在bean实例化之前,读取bean的定义,并可以修改它。
  43. */
  44. invokeBeanFactoryPostProcessors(beanFactory);
  45. // Register bean processors that intercept bean creation.
  46. // 注册Bean的后置处理器
  47. // 本方法会注册所有的 BeanPostProcessor,将所有实现了 BeanPostProcessor 接口的类加载到 BeanFactory 中。
  48. registerBeanPostProcessors(beanFactory);
  49. // Initialize message source for this context.
  50. initMessageSource();
  51. // Initialize event multicaster for this context.
  52. initApplicationEventMulticaster();
  53. // Initialize other special beans in specific context subclasses.
  54. onRefresh();
  55. // Check for listener beans and register them.
  56. registerListeners();
  57. // Instantiate all remaining (non-lazy-init) singletons.
  58. /*
  59. * 初始化所有剩下的非懒加载的单例Bean
  60. * 创建非懒加载方式的单例Bean
  61. * 设置Bean的属性
  62. * 初始化方法调用
  63. * 调动BeanPostProcessor对实例Bean进行后置处理
  64. */
  65. finishBeanFactoryInitialization(beanFactory);
  66. // Last step: publish corresponding event.
  67. finishRefresh();
  68. }
  69. catch (BeansException ex) {
  70. if (logger.isWarnEnabled()) {
  71. logger.warn("Exception encountered during context initialization - " +
  72. "cancelling refresh attempt: " + ex);
  73. }
  74. // Destroy already created singletons to avoid dangling resources.
  75. destroyBeans();
  76. // Reset 'active' flag.
  77. cancelRefresh(ex);
  78. // Propagate exception to caller.
  79. throw ex;
  80. }
  81. finally {
  82. // Reset common introspection caches in Spring's core, since we
  83. // might not ever need metadata for singleton beans anymore...
  84. resetCommonCaches();
  85. }
  86. }
  87. }

获取BeanFactory与加载BeanDefinitions

**ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();**
**obtainFreshBeanFactory()**

  1. /**
  2. * Tell the subclass to refresh the internal bean factory.
  3. * @return the fresh BeanFactory instance
  4. * @see #refreshBeanFactory()
  5. * @see #getBeanFactory()
  6. */
  7. protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
  8. refreshBeanFactory();
  9. return getBeanFactory();
  10. }

image.png

BeanDefinition

什么是BeanDefinition
  • BeanDefinition描述一个bean实例,该实例具有属性值、构造函数参数值和由具体实现提供的进一步信息。
  • BeanDefinition里存着bean的属性值,构造函数等等的信息。
  • 其实就是将xml里的bean属性,存到了BeanDefinition的某些属性里面,用的时候,从BeanDefinition的这些属性里取值。
  • 另外我们可以通过BeanFactoryPostProcessor来修改加载到BeanDefinition对象中的bean的属性。
    BeanDefinition设置过程的调用链
    ApplicationContext-BeanDefinition调用过程.jpg

    Bean对象的创建流程

    IoC-创建Bean的调用链.jpg
    **beanFactory.preInstantiateSingletons();**
    image.png
  1. 先处理FactoryBean
  2. 然后创建普通Bean,走getBean()方法
  3. doGetBean()方法
  4. 做一些基础设置
  5. 以创建单例Bean为例:

image.png

Bean初始化的主体类

image.png
spring bean 的流程全在 AbstractAutowireCapableBeanFactory 类中实现

  1. 在第5步的createBean,调用AbstractAutowireCapableBeanFactory实现的createBean方法

image.png

  1. doCreateBean(beanName, mbdToUse, args);中的流程即是SpringBean的生命周期
    1. 通过反射创建单例Bean:instanceWrapper = createBeanInstance(beanName, mbd, args);
    2. 设置Bean的属性:populateBean(beanName, mbd, instanceWrapper);
    3. initializeBean(beanName, exposedObject, mbd);方法中:
      1. 检查Aware借口并设置相关依赖

image.png

  1. 2. **设置BeanPostProcessors 前置处理器**

image.png

  1. 3. **初始化方法**

image.png

  1. 4. **BeanPostProcessors 后置处理器**

image.png

延迟加载

getBean的时候才能调用

循环依赖

无法解决

  • 原型Bean的循环依赖无法解决
  • 单例Bean构造器参数循环依赖无法解决

可以解决

  • 单例Bean通过set方法或者@Autowired注入依赖

下图是解决A、B循环依赖的简单原理:
ApplicationContext-解决循环依赖原理.jpg

循环依赖解决原理

假设Class A 和Class B 相互依赖

  1. 初始化A的过程中,先通过构造器生成A的实例,把他提前暴露到spring容器中(singletonFactories三级缓存);(生命周期种的7.a)

image.png

  1. 给A设置属性populateBean(beanName, mbd, instanceWrapper);(生命周期种的7.b)
  2. 发现A依赖于B;populateBean—>applyPropertyValues(beanName, mbd, bw, pvs)image.pngimage.pngimage.pngAbstractBeanFactory image.png
  3. 开始创建B,设置属性之前 同创建A的流程一样;(这里就又回生命周期的2)
  4. 设置属性时发现依赖于A,同样和3的流程一样,直到走到AbstractBeanFactorydoGetBean方法。

doGetBean方法中的getSingleton从缓存中获取A
image.png

  1. 首先从一级缓存(singletonObjects)中获取,如果没有,然后二级缓存(earlySingletonObjects),然后三级缓存(singletonFactories),从三级缓存中拿到A的幼年期对象,然后加入了二级缓存;并从三级缓存中删除。

image.png

  1. 返回A的 幼年期(未创建完全)对象
  2. 创建B完成,加入一级缓存
  3. A从一级缓存中,获取B的依赖

2. Spring AOP

首先,springAOP是通过生成类的代理对象,进行方法增强,
所以,这时候正好就用到了beanPostProcesser
image.png

image.png

image.png