Spring 是一个 IOC 容器框架,拥有 DI 依赖注入(Dependency Injection),DL 依赖查找(Dependency Lookup)等功能。下面是根据源码分析出四个阶段,做出的生命周期解读:

  • 注册阶段
  • 实例化阶段
  • 初始化阶段
  • 销毁阶段

2021-05-03-10-54-29-611324.png
从图中可以看到,Bean 的完整生命周期从 Spring 容器着手实例化 Bean 开始,直到最终销毁 Bean。其中经历了许多关键点,可以将这些方法大致划分为 3 类:

  • Bean 自身的方法:如调用构造函数实例化、调用 Setter 设置属性值以及 init-method、destroy-method 指定的方法。

  • Bean 级生命周期接口方法:如 Aware 接口的属性赋值、InitializingBean、DisposableBean 接口

  • 容器级生命周期接口方法,主要由 InstantiationAwareBeanPostProcessor 和 BeanPostProcessor 两个接口实现,一般称它们的实现类为后处理器。后处理器以容器附加装置的形式注册到 Spring 容器中,当 Spring 容器创建任何 Bean 时,这些后处理器都会发生作用,所以这些后处理器的影响是全局性的。

注册阶段

注册阶段主要任务是通过各种 BeanDefinitionReader 读取扫描各种配置来源信息(XML 文件、注解等),并转换为 BeanDefinition 的过程。然后,最终会将扫描到的类整体注册到一个 DefaultListableBeanFactory 的 Map 容器中,便于之后获取使用。

1. BeanDefinition

BeanDefinition 可以理解为类的定义,描述一个类的基本情况。它完整的描述了在 Spring 的配置文件中定义的 节点中所有的信息,或者通过注解定义的 Bean 信息。当 Spring 成功解析定义的一个 节点后,在 Spring 内部就被转化成 BeanDefinition 对象,以后所有的操作都是对这个对象完成的。
image.png

2. BeanDefinitionReader

Bean 的解析过程非常复杂,功能被分的很细,因为这里需要被扩展的地方很多,必须保证有足够的灵活性,以应对可能的变化。Bean 的解析主要就是对 Spring 配置文件或注解信息的解析。这个解析过程主要通过下图中的类完成:
image.png

3. SpringBoot 注册

在 Spring Boot 中,注册 Bean 的入口就是 run 方法中的 prepareContext 方法:

  1. public ConfigurableApplicationContext run(String... args) {
  2. ......
  3. prepareContext(context, environment, listeners, applicationArguments, printedBanner);
  4. ......
  5. }

在 prepareContext 方法中,会创建一个 BeanDefinitionLoader 对象,并执行它的 load 方法:

  1. protected void load(ApplicationContext context, Object[] sources) {
  2. BeanDefinitionLoader loader = createBeanDefinitionLoader(getBeanDefinitionRegistry(context), sources);
  3. if (this.beanNameGenerator != null) {
  4. loader.setBeanNameGenerator(this.beanNameGenerator);
  5. }
  6. if (this.resourceLoader != null) {
  7. loader.setResourceLoader(this.resourceLoader);
  8. }
  9. if (this.environment != null) {
  10. loader.setEnvironment(this.environment);
  11. }
  12. loader.load();
  13. }

在 BeanDefinitionLoader 的 load 方法中,会通过 AnnotatedBeanDefinitionReader 来读取 Spring Boot 启动类上的注解信息,进而注册 Bean。

  1. private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
  2. @Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
  3. @Nullable BeanDefinitionCustomizer[] customizers) {
  4. // 生成BeanDefinition信息
  5. AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
  6. // 判断是否有@Conditional注解,以及是否满足bean注册条件
  7. if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
  8. return;
  9. }
  10. // 解析@Scope注解,确定Bean作用范围
  11. ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
  12. abd.setScope(scopeMetadata.getScopeName());
  13. // 生成Bean名称
  14. String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
  15. // 处理Bean相关的通用注解,如@Lazy、@Primary、@DependsOn等
  16. AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
  17. ...
  18. // 允许对BeanDefinition进行一些自定义修改
  19. if (customizers != null) {
  20. for (BeanDefinitionCustomizer customizer : customizers) {
  21. customizer.customize(abd);
  22. }
  23. }
  24. // 默认作用域为单例且不进行代理
  25. BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
  26. definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
  27. // 向容器中注册Bean定义信息
  28. BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
  29. }

在 registerBeanDefinition 方法中,最终会注册到 DefaultListableBeanFactory 容器中:

  1. public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
  2. // 存储注册信息的BeanDefinition
  3. private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
  4. // beanDefinitionMap的数据结构是ConcurrentHashMap,因此不能保证顺序,为了记录注册的顺序,这里使用了ArrayList类型beanDefinitionNames用来记录注册顺序
  5. private volatile List<String> beanDefinitionNames = new ArrayList<>(256);
  6. @Override
  7. public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException {
  8. ......
  9. // 注册过程
  10. this.beanDefinitionMap.put(beanName, beanDefinition);
  11. this.beanDefinitionNames.add(beanName);
  12. }
  13. }

4. 相关注解配置

Spring 提供了 @Component、@Repository、@Service、@Controller 注解,因此我们可以使用特定的注解标注特定的 Bean。标注好 Bean 后,可以通过 @ComponentScan 注解扫描指定类路径来加载 Bean。

Bean 加载过程:

Spring 可以通过 @Autowired 进行自动注入,该注解可以作用在变量、setter 方法、构造函数上,默认通过类型匹配的方式在容器中查找匹配的 Bean,如果容器中没有类型匹配的 Bean,那么 Spring 容器启动时将抛出 NoSuchBeanDefinitionException 异常。可以将其 required 属性设置为 false 避免在匹配不到 Bean 时抛出异常。如果容器中有一个以上匹配的 Bean 时,则可以通过 @Qualifier 注解限定 Bean 的名称(byName)。

如果对集合类的变量进行 @Autowired 标注,那么 Spring 会将容器中匹配集合元素类型的所有 Bean 都自动注入进来。默认情况下,Bean 注入的顺序是不确定的,我们可以通过 @Order 注解或实现 Ordered 接口来决定 Bean 加载的顺序,值越小越优先被加载。

此外,Spring 还支持延迟依赖注入,即在 Spring 容器启动时,对于在 Bean 上标注 @Lazy 及 @Autowired 注解的属性,不会立即注入属性值,而是延迟到调用此属性的时候才会注入属性值。对 Bean 实施依赖注入时,@Lazy 注解必须同时标注在属性及目标 Bean 上。

  1. @Lazy
  2. @Component
  3. public class AppQuotaOne {
  4. }
  5. @Component
  6. public class AppQuotaSpringTest {
  7. @Lazy
  8. @Autowired
  9. private AppQuota appQuotas;
  10. }

Spring 也支持 @Resource 标准注解,@Resource 注解要求提供一个 Bean 名称的属性(byName),如果属性为空,则自动采用标注处的变量名或方法名作为 Bean 的名称。

Bean 作用范围及生命过程方法:

通过注解配置的 Bean 和通过 配置的 Bean 一样,默认作用范围都是 singleton。Spring 为注解配置提供了一个 @Scope 注解,可以通过它显式指定 Bean 的作用范围。其作用域类型如下:

| singleton | 在 Spring IoC 容器中仅存在一个 Bean 实例,Bean 以单例方式存在。

默认 ApplicationContext 容器在启动时会自动实例化所有 singleton 的 Bean 并缓存于容器中,这样当运行时就无须实例化了。如果用户不希望提前实例化,可以通过 lazy-init 属性进行控制 | | —- | —- | | prototype | 每次从容器中调用 Bean 时,都返回一个新的实例,即每次调用 getBean() 时,相当于执行 new XXXBean() 操作。Spring 容器启动时不会实例化 prototype 的 Bean | | request | 每次 HTTP 请求都会创建一个新的 Bean,该作用域仅适用于 WebApplicationContext | | session | 同一个 HTTP Session 共享一个 Bean,不同的 HTTP Session 使用不同的 Bean,该作用域仅适用于 WebApplicationContext | | globalSession | 同一个全局 Session 共享一个 Bean,该作用域仅适用于 WebApplicationContext |

在使用 进行配置时,可以通过 init-methoddestory-method 属性指定 Bean 的初始化及容器销毁前执行的方法。Spring 也为其提供了相应的 @PostConstruct 和 @PreDestory 注解,不过在使用注解时,可以在一个 Bean 里定义多个该注解方法。

使用 Java 类提供 Bean 定义信息:

普通的 POJO 只要标注 @Configuration 注解,就可以为 Spring 容器提供 Bean 定义信息,每个标注了 @Bean 的类方法都相当于提供了一个 Bean 的定义信息。Bean 的类型由方法返回值的类型决定,名称默认和方法名相同(也可通过 name 属性显示指定名称)。@Bean 所标注的方法体提供了 Bean 的实例化逻辑。

Spring 提供了一个 AnnotationConfigApplicationContext 类,它能够直接通过标注 @Configuration 的 Java 类启动 Spring 容器。此外,还支持手动加载多个配置类,然后通过刷新容器应用这些配置类。Spring 也提供了一个 @Import 注解将多个配置类组装到一个配置类中,这样仅需要注册这个组装好的配置类即可启动容器。

实例化阶段

当 IOC 容器启动并装载 Bean 之后,并不会直接初始化 Bean,而是等到第一次调用的时候才会去初始化。在实例化阶段,Spring 主要将 BeanDefinition 转换为实例 Bean,并放在包装类 BeanWrapper 中。无论是否设置 Bean 的懒加载方式,最后都会通过 AbstractBeanFactory.getBean() 方法进行实例化:

  1. protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
  2. @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
  3. // 获取beanName
  4. final String beanName = transformedBeanName(name);
  5. Object bean;
  6. // 检查缓存中或者singletonFactories中的ObjectFactory中是否有对应的实例
  7. // 因为在创建单例bean的时候会存在依赖注入的情况,而在创建依赖时为了避免循环依赖,
  8. // Spring创建bean的原则是不等bean创建完成就会将创建bean的ObjectFactory提早曝光
  9. // 也就是将ObjectFactory加入到缓存中,一旦下个 bean 创建时要依赖上个 bean 则直接使用ObjectFactory
  10. Object sharedInstance = getSingleton(beanName);
  11. if (sharedInstance != null && args == null) {
  12. ...
  13. // 返回对应的实例,有时存在诸如FactoryBean的情况并不是直接返回实例本身而是返回指定方法返回的实例
  14. bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
  15. }
  16. else {
  17. // 只有在单例情况下才会尝试解决循环依赖
  18. if (isPrototypeCurrentlyInCreation(beanName)) {
  19. throw new BeanCurrentlyInCreationException(beanName);
  20. }
  21. BeanFactory parentBeanFactory = getParentBeanFactory();
  22. // 如果在当前所有已加载的类中不包含beanName,则尝试从parentBeanFactory中检测
  23. if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
  24. String nameToLookup = originalBeanName(name);
  25. if (parentBeanFactory instanceof AbstractBeanFactory) {
  26. return ((AbstractBeanFactory) parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly);
  27. } else if (args != null) {
  28. return (T) parentBeanFactory.getBean(nameToLookup, args);
  29. } else if (requiredType != null) {
  30. return parentBeanFactory.getBean(nameToLookup, requiredType);
  31. } else {
  32. return (T) parentBeanFactory.getBean(nameToLookup);
  33. }
  34. }
  35. try {
  36. final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
  37. checkMergedBeanDefinition(mbd, beanName, args);
  38. String[] dependsOn = mbd.getDependsOn();
  39. // 若存在依赖则需要递归实例化依赖的bean
  40. if (dependsOn != null) {
  41. for (String dep : dependsOn) {
  42. // 缓存依赖调用关系
  43. registerDependentBean(dep, beanName);
  44. getBean(dep);
  45. }
  46. }
  47. // 实例化依赖的 bean 后便可以实例化自身了
  48. // 单例模式创建bean
  49. if (mbd.isSingleton()) {
  50. sharedInstance = getSingleton(beanName, () -> {
  51. try {
  52. // 创建bean实例
  53. return createBean(beanName, mbd, args);
  54. } catch (BeansException ex) {
  55. destroySingleton(beanName);
  56. throw ex;
  57. }
  58. });
  59. bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
  60. }
  61. // 原型模式创建bean
  62. else if (mbd.isPrototype()) {
  63. Object prototypeInstance = null;
  64. try {
  65. beforePrototypeCreation(beanName);
  66. prototypeInstance = createBean(beanName, mbd, args);
  67. } finally {
  68. afterPrototypeCreation(beanName);
  69. }
  70. bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
  71. }
  72. // 指定的scope上实例化bean
  73. else {
  74. String scopeName = mbd.getScope();
  75. final Scope scope = this.scopes.get(scopeName);
  76. try {
  77. Object scopedInstance = scope.get(beanName, () -> {
  78. beforePrototypeCreation(beanName);
  79. try {
  80. return createBean(beanName, mbd, args);
  81. } finally {
  82. afterPrototypeCreation(beanName);
  83. }
  84. });
  85. bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
  86. }
  87. }
  88. }
  89. }
  90. // 检查需要的类型是否符合实际的类型
  91. if (requiredType != null && !requiredType.isInstance(bean)) {
  92. try {
  93. T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
  94. if (convertedBean == null) {
  95. throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
  96. }
  97. return convertedBean;
  98. }
  99. }
  100. return (T) bean;
  101. }

1. FactoryBean

一般情况下,Spring 通过反射机制利用 bean 的 class 属性指定实现类来实例化 bean。但在某些情况下,实例化 bean 过程比较复杂,如果按照传统的方式,则需要在 中提供大量的配置信息,配置方式的灵活性是受限的,这时采用编码的方式可能会得到一个简单的方案。Spring 为此提供了一个 FactoryBean 的工厂类接口,用户可以通过实现该接口定制实例化 bean 的逻辑。

  1. public interface FactoryBean<T> {
  2. // 返回由FactoryBean创建的Bean实例,如果isSingleton()返回true,则该实例还会放到Spring容器的单实例缓存池中
  3. T getObject() throws Exception;
  4. // 返回由FactoryBean创建的Bean的类型
  5. Class<?> getObjectType();
  6. // 确定由FactoryBean创建的Bean的作用域是singleton还是prototype
  7. default boolean isSingleton() { return true; }
  8. }

配置的实现类是 FactoryBean 时,通过 getBean() 方法返回的不是 FactoryBean 本身,而是FactoryBean#getObject() 方法所返回的对象,相当于 FactoryBean#getObject() 代理了 getBean() 方法。如果希望获取 FactoryBean 本身的实例,则需要在使用 getBean(beanName) 方法时在 beanName 前显示的加上 &前缀。

2. getObjectForBeanInstance

在 getBean 方法中,getObjectForBeanlnstance 是个高频率使用的方法,无论是从缓存中获得 bean 还是根据不同的 scope 策略加载 bean。总之,我们得到 bean 的实例后要做的第一步就是调用这个方法来检测一下正确性,其实就是用于检测当前 bean 是否是 FactoryBean 类型的 bean,如果是,那么需要调用该 bean 对应的 FactoryBean 实例中的 getObject() 作为返回值。

  1. protected Object getObjectForBeanInstance(Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
  2. // name是否以&为前缀
  3. if (BeanFactoryUtils.isFactoryDereference(name)) {
  4. if (beanInstance instanceof NullBean) {
  5. return beanInstance;
  6. }
  7. // 如果指定的name是工厂相关(以&为前缀)且beanInstance又不是FactoryBean类型则验证不通过
  8. if (!(beanInstance instanceof FactoryBean)) {
  9. throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
  10. }
  11. if (mbd != null) {
  12. mbd.isFactoryBean = true;
  13. }
  14. // 返回FactoryBean自身
  15. return beanInstance;
  16. }
  17. // 普通bean直接返回
  18. if (!(beanInstance instanceof FactoryBean)) {
  19. return beanInstance;
  20. }
  21. // 加载FactoryBean
  22. Object object = null;
  23. if (mbd != null) {
  24. mbd.isFactoryBean = true;
  25. } else {
  26. // 尝试从缓存中加载bean
  27. object = getCachedObjectForFactoryBean(beanName);
  28. }
  29. if (object == null) {
  30. FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
  31. if (mbd == null && containsBeanDefinition(beanName)) {
  32. mbd = getMergedLocalBeanDefinition(beanName);
  33. }
  34. boolean synthetic = (mbd != null && mbd.isSynthetic());
  35. // 调用FactoryBean的getObject方法返回自定义的bean实例
  36. object = getObjectFromFactoryBean(factory, beanName, !synthetic);
  37. }
  38. return object;
  39. }

3. getSingleton

在 Spring 加载 Bean 的过程中使用了 getSingleton 方法实现单例 Bean 的加载过程:

  1. public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
  2. // 全局变量需要同步
  3. synchronized (this.singletonObjects) {
  4. // 首先检查对应的bean是否已经加载过,因为singleton模式其实就是复用已创建的bean,所以这一步是必须的
  5. Object singletonObject = this.singletonObjects.get(beanName);
  6. // 如果为空才可以进行singleton的bean的初始化
  7. if (singletonObject == null) {
  8. // 单例创建之前的回调
  9. beforeSingletonCreation(beanName);
  10. boolean newSingleton = false;
  11. boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
  12. if (recordSuppressedExceptions) {
  13. this.suppressedExceptions = new LinkedHashSet<>();
  14. }
  15. try {
  16. // 初始化bean
  17. singletonObject = singletonFactory.getObject();
  18. newSingleton = true;
  19. } finally {
  20. if (recordSuppressedExceptions) {
  21. this.suppressedExceptions = null;
  22. }
  23. // 单例创建后的回调
  24. afterSingletonCreation(beanName);
  25. }
  26. if (newSingleton) {
  27. // 加入缓存
  28. addSingleton(beanName, singletonObject);
  29. }
  30. }
  31. return singletonObject;
  32. }
  33. }

上述代码中其实是使用了回调方法,使得程序可以在单例创建的前后做一些准备及处理操作,而真正的获取单例 bean 的方法其实并不是在此方法中实现的,其实现逻辑是在 ObjectFactory 类型的实例 singletonFactory 中实现的。

4. createBean

ObjectFactory 中真正创建 Bean 的动作是由外部传入的一个函数来实际执行的,即 AbstractFactoryBean 中的 creatBean 方法。在 createBean 的方法实现中,其子类 AbstractAutowireCapableBeanFactory 又重写了该方法,具体如下:

  1. @Override
  2. protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
  3. throws BeanCreationException {
  4. RootBeanDefinition mbdToUse = mbd;
  5. // 根据设置的 class 属性或者根据 className 来解析 Class
  6. Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
  7. if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
  8. mbdToUse = new RootBeanDefinition(mbd);
  9. mbdToUse.setBeanClass(resolvedClass);
  10. }
  11. // 验证及准备覆盖的方法
  12. mbdToUse.prepareMethodOverrides();
  13. try {
  14. // 给BeanPostProcessors一个机会来返回代理来替代真正的对象
  15. Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
  16. if (bean != null) {
  17. return bean;
  18. }
  19. }
  20. try {
  21. // 真正创建bean的动作
  22. Object beanInstance = doCreateBean(beanName, mbdToUse, args);
  23. return beanInstance;
  24. }
  25. }

在真正调用 doCreateBean 方法创建 bean 的实例前调用了 resolveBeforeInstantiation 方法对 BeanDefiniton 中的属性做些前置处理。

  1. protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
  2. Object bean = null;
  3. // 如果尚未被解析
  4. if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
  5. if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
  6. Class<?> targetType = determineTargetType(beanName, mbd);
  7. if (targetType != null) {
  8. bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
  9. if (bean != null) {
  10. bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
  11. }
  12. }
  13. }
  14. mbd.beforeInstantiationResolved = (bean != null);
  15. }
  16. return bean;
  17. }
  • 实例化前的后处理器应用:applyBeanPostProcessorsBeforeInstantiation
  • 实例化后的后处理器应用:applyBeanPostProcessorsAfterInitialization

5. doCreateBean

当经历过 resolveBeforeInstantiation 方法后,程序有两个选择,如果创建了代理或者说重写了 InstantiationAwareBeanPostProcessor 的 postProcessBeforeInstantiation 方法并在方法中改变了 bean,则直接返回就可以了,否则需要进行常规 bean 的创建。而常规 bean 的创建就是在 doCreateBean 中完成的。

  1. protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
  2. throws BeanCreationException {
  3. // Instantiate the bean.
  4. BeanWrapper instanceWrapper = null;
  5. if (mbd.isSingleton()) {
  6. instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
  7. }
  8. if (instanceWrapper == null) {
  9. // 根据指定bean使用对应的策略创建新的实例,如:工厂方法、构造函数自动注入、简单初始化
  10. instanceWrapper = createBeanInstance(beanName, mbd, args);
  11. }
  12. final Object bean = instanceWrapper.getWrappedInstance();
  13. Class<?> beanType = instanceWrapper.getWrappedClass();
  14. if (beanType != NullBean.class) {
  15. mbd.resolvedTargetType = beanType;
  16. }
  17. // 应用MergedBeanDefinitionPostProcessor后处理器
  18. synchronized (mbd.postProcessingLock) {
  19. if (!mbd.postProcessed) {
  20. try {
  21. applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
  22. }
  23. mbd.postProcessed = true;
  24. }
  25. }
  26. // 是否需要提早曝光:单例、允许循环依赖、当前bean正在创建中,检测循环依赖
  27. boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
  28. isSingletonCurrentlyInCreation(beanName));
  29. if (earlySingletonExposure) {
  30. // 为避免后期循环依赖,可以在 bean 初始化完成前将创建实例的 ObjectFactory 加入工厂
  31. // getEarlyBeanReference中主要应用SmartInstantiationAwareBeanPostProcessor处理器,AOP的动态织入就是在这里完成的
  32. addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
  33. }
  34. Object exposedObject = bean;
  35. try {
  36. // 对bean进行填充,将各个属性值注入,其中可能存在依赖于其他bean的属性,则会递归初始依赖bean
  37. populateBean(beanName, mbd, instanceWrapper);
  38. // 激活Aware接口,注入相应的实例
  39. // 调用BeanPostProcessor的postProcessBeforeInitialization
  40. // 调用bean的初始化方法,比如InitializingBean接口的afterPropertiesSet方法
  41. // 调用BeanPostProcessor的postProcessAfterInitialization
  42. exposedObject = initializeBean(beanName, exposedObject, mbd);
  43. }
  44. if (earlySingletonExposure) {
  45. Object earlySingletonReference = getSingleton(beanName, false);
  46. // earlySingletonReference只有在检测到有循环依赖的情况下才会不为空
  47. if (earlySingletonReference != null) {
  48. // 如果 exposedObject 没有在初始化方法中被改变,也就是没有被增强
  49. if (exposedObject == bean) {
  50. exposedObject = earlySingletonReference;
  51. } else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
  52. String[] dependentBeans = getDependentBeans(beanName);
  53. Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
  54. // 检测依赖
  55. for (String dependentBean : dependentBeans) {
  56. if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
  57. actualDependentBeans.add(dependentBean);
  58. }
  59. }
  60. // 因为bean创建后其所依赖的bean一定是已创建的
  61. // actualDependentBeans不为空则表示当前bean创建后其依赖的bean却没有全部创建完,也就是说存在循环依赖
  62. if (!actualDependentBeans.isEmpty()) {
  63. throw new BeanCurrentlyInCreationException(...);
  64. }
  65. }
  66. }
  67. }
  68. // 注册DisposableBean,如果配置了destroy-method,这里需要注册以便于在销毁时候调用
  69. registerDisposableBeanIfNecessary(beanName, bean, mbd);
  70. return exposedObject;
  71. }

BeanWrapper 相当于一个代理器,Spring 委托 BeanWrapper 完成 Bean 属性的填充工作。这是通过调用 setWrappedInstance(Object obj) 方法完成的。

BeanWrapper 还有两个顶级类接口:PropertyAccessor 和 PropertyEditorRegistry。前者定义了各种访问 Bean 属性的方法,而后者是属性编辑器的注册表。Spring 从 BeanDefinition 中获取 Bean 属性的配置信息 PropertyValue,并使用属性编辑器对 PropertyValue 进行转换以得到 Bean 的属性值。

初始化阶段

初始化阶段主要是在返回 Bean 实例之前做一些处理,主要由 AbstractAutowireCapableBeanFactory 提供的 initializeBean() 方法来实现。

  1. protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
  2. // JDK的安全机制验证权限
  3. if (System.getSecurityManager() != null) {
  4. AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
  5. invokeAwareMethods(beanName, bean);
  6. return null;
  7. }, getAccessControlContext());
  8. } else {
  9. // 为Bean注入相应的Aware接口表示的实例
  10. invokeAwareMethods(beanName, bean);
  11. }
  12. Object wrappedBean = bean;
  13. // 对BeanPostProcessor后置处理器的postProcessBeforeInitialization回调方法的调用,为Bean实例初始化前做一些处理
  14. if (mbd == null || !mbd.isSynthetic()) {
  15. wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
  16. }
  17. try {
  18. // 调用Bean实例对象初始化的方法,这个初始化方法是在Spring Bean定义配置文件中通过init-method属性指定的
  19. // 或者实现了InitializingBean接口的afterPropertiesSet方法
  20. invokeInitMethods(beanName, wrappedBean, mbd);
  21. }
  22. // 对BeanPostProcessor后置处理器的postProcessAfterInitialization回调方法的调用,为Bean实例初始化之后做一些处理
  23. if (mbd == null || !mbd.isSynthetic()) {
  24. wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
  25. }
  26. return wrappedBean;
  27. }

Spring Aware 的目的是为了让 Bean 获得 Spring 容器的服务,常用的 Aware 接口如下:

BeanNameAware 获取到容器中 Bean 的名称
BeanFactoryAware 获取当前 BeanFactory,这样可以调用容器的服务
ApplicationContextAware 获取当前 ApplicationContext,这样可以调用容器的服务
ApplicationEventPublisherAware 获取 ApplicationEventPublisher,可以发布事件
ResourceLoaderAware 获得资源加载器,可以获得外部资源文件

销毁阶段

一般是在 ApplicationContext 关闭的时候调用,也就是 AbstractApplicationContext.close() 方法。在注册的时候 Spring 通过适配器模式包装了一个类 DisposableBeanAdapter,在销毁阶段的时候会获得这个类,进而调用到 DisposableBeanAdapter.destroy() 方法:

  1. public void destroy() {
  2. // @PreDestroy注解的支持
  3. if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {
  4. for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) {
  5. processor.postProcessBeforeDestruction(this.bean, this.beanName);
  6. }
  7. }
  8. // DisposableBean接口的支持
  9. if (this.invokeDisposableBean) {
  10. ((DisposableBean) this.bean).destroy();
  11. }
  12. if (this.destroyMethod != null) {
  13. invokeCustomDestroyMethod(this.destroyMethod);
  14. } else if (this.destroyMethodName != null) {
  15. Method methodToInvoke = determineDestroyMethod(this.destroyMethodName);
  16. if (methodToInvoke != null) {
  17. invokeCustomDestroyMethod(ClassUtils.getInterfaceMethodIfPossible(methodToInvoke));
  18. }
  19. }
  20. }

销毁阶段主要包括三个销毁途径,按照如下执行顺序:

  • @PreDestroy 注解,主要通过 DestructionAwareBeanPostProcessor 实现
  • 实现 DisposableBean 接口,主要通过 DisposableBean.destroy() 实现
  • 自定义销毁方 DisposableBeanAdapter.invokeCustomDestroyMethod() 实现