-->

Spring源码之后置处理器(BeanPostProcessor)

2019-11-15 19:49发布

1.Spring refresh过程中执行的beanPostProcessor

名称 执行的方法 作用
instantiationAwareBeanPostProcessor postPorcessorBeforeInstantiation 对目标对象的初始化过程中需要处理的事情
smartInstantiationAwareBeanPostProcessor determineCandidateConstructors 推断构造方法
mergedBeanDefinitionBeanPostProcessor postProcessorMergedBeanDefinition
smartInstantiationAwareBeanPostProcessor getEarlyBeanReference
instantiationAwareBeanPostProcessor postProcessorPropertyValues
smartBeanPostProcessor
BeanPostProcessor postProcessBeforeInitialization
BeanPostProcessor postProcessAfterInitialization

getBean获取提前暴露出来的对象

beanDefinitionNames

1、核心beanPostProcessor

1.1.instantiationAwareBeanPostProcessor:

方法一: postProcessorBeforeInstantation:实例化之前执行,如果该方法返回了Object,后面只执行postProcessorAfterInitialization方法,其它方法不再调用。

方法二:postProcessorAfterInstantation:实例化之后调用。

方法三:postProcessorPropertyValues:设置对象属性。

方法四:postProcessorBeforeInitialization:bean初始化之前执行,此时目标对象已经被实例化且属性已经被设置。

方法五:postPorocessorAfterInitialization:bean初始化之前执行,此时目标对象已经被实例化且属性已经被设置。

1.2.smartInstantiationAwareBeanPostProcessor

方法一:determineCandidateConstructors:检测出bean的构造函数。

方法二:getEarlyBeanReference:解决循环引用问题的后置处理器,获取提前暴露的引用。

1.3.mergedBeanDefinitionBeanPostProcessor

方法一:postProcessorMergedBeanDefinition:获取bean的注入信息,并缓存起来

常见beanPostProcessor:

例子:

2、代码跟踪

2.1.mergedBeanDefinitionBeanPostProcessor

2.1.1.commonAnnocationAwareBeanPostProcessor
  1. 执行postProcessMergedBeanDefinition方法:2. 第一步是执行父类InitDestroyAnnotationBeanPostProcessor的方法postProcessMergedBeanDefinition,从类名上也能很明显看出,初始化和销毁注解后置处理器。

  2. 我们进入findLifecycleMetadata,先从缓存里找,没有找到,继续往下走。重点是buildResourceMetadata方法,我们进入buildResourceMetadata看看。

  3. 执行buildLifecycleMetadata方法,到此父类InitDestroyAnnotationBeanPostProcessor的方法postProcessMergedBeanDefinition已经执行完毕。

  4. 第二步执行findResourceMetadata方法

    先从缓存里找,没有找到,继续往下走。重点是buildResourceMetadata方法,我们进入buildResourceMetadata看看。

  5. 执行buildResourceMetadata方法,下面我们看下关键的方法

    到此核心的功能已经执行完毕。主要的作用就是找出@PostConstruct和@PreDestroy注解修饰的方法,放入到lifecycleMetadataCache缓存中;@Resource修饰的方法或者变量,放入到injectionMetadataCache缓存中。

2.1.2.autowiredAnnotationBeanPostProcessor
  1. 同样,也是执行postProcessMergedBeanDefinition方法
  2. 执行findAutowiringMetadata,先从缓存里找,没有找到,继续往下走。重点是buildAutowiringMetadata方法,我们进入buildAutowiringMetadata看看。
  3. 进入buildAutowiringMetadata方法,先利用反射,遍历类所有的field,找出是否使用@Auwired 和@Value注解的field

    再遍历类所有的method,找出是否使用@Auwired 和@Value注解的method
  4. 最后放入到injectionMetadataCache缓存中。到此核心的功能已经执行完毕。主要是找出@Value和@Autowired修饰的变量和方法,并放入到缓存中。

2.2.instantiationAwareBeanPostProcessor

2.2.1.commonAnnotationaBeanPostProcessor:
注入@Resource修饰的属性的bean。
  1. 执行postProcessPropertyValues方法。

    这里我们又看到了findResourceMetadata方法,这次直接就可以从commonAnnocationAwareBeanPostProcessor类的injectionMetadataCache缓存中拿出来InjectionMetadata属性。再调用inject方法
2.2.2.autowiredAnnotationBeanPostProcessor:
找出@Value和@Autowired修饰的变量和方法


执行postProcessPropertyValues方法,进入findAutowiringMetadata方法,从方法名也能看出来,是找出被@Autowired修饰的属性,得到InjectionMetadata属性

3. 这里同样直接就可以从AutowiredAnnotationBeanPostProcessor类的injectionMetadataCache缓存中拿出来InjectionMetadata属性。再调用inject方法。

2.3.smartInstantiationAwareBeanPostProcessor

三、beanPostProcessor

1.ApplicationContextAwareProcessor: 定义一个bean实现ApplicationContextAware接口可以使它获取到applicationContext应用上下文。

Spring是如何解决循环依赖:

概念说明:

Spring容器:

singletonObejcts (conCurrentHashMap) ,里面存放交给Spring管理的bean,bean已经完全初始化好。

singletonFactories (hashMap) ,存放用来获取提前暴露bean引用的ObjectFactory对象。

earlySingletonObjects(hashMap),存放原始的bean对象,属性还未填充。

A依赖B B依赖A

  1. 属性B(getSingleton(A)),实例化A,注入属性B,获取属性B(getSingleton(B))
  2. 实例化B,注入属性A,获取属性A(getSingleton(A))

    首先从singletonObjects,也就是Spring容器获取,第一次getSingleton(A),singletonObjects返回空,且isSingletonCurrentlyInCreation(A)返回空,

Spring初始化方法和销毁方法:

  1. @PostConstruct和@PreDestroy注解的方法
  2. 实现InitializingBean接口和DisposableBean接口
  3. @Bean 的属性 initMethod和destroyMethod方法
标签: