Spring的BeanPostProcessor及部分默认实现

Bean处理器

BeanPostProcessor

工厂钩子方法,用于修改新创建的bean(e.g 代理)

Factory hook that allows for custom modification of new bean
instances ; for example, checking for marker interfaces or wrapping beans with proxies.

  1. 注册
  • ApplicationContext自动检测
    通过注解让spring自动扫描,应用于随后bean的创建(即在此BeanPostProcessor创建后的所有bean都会被应用)

ApplicationContext can autodetect BeanPostProcessor
beans in its bean definitions and apply those post-processors to
any beans subsequently created.

  • BeanFactory编码注册
    在整个BeanFactoty的bean创建期间都会应用。
  1. 排序
    编程注册的按照注入顺序执行,忽略优先级,自动扫描的按照PriorityOrdered,Ordered的优先级来执行。
InstantiationAwareBeanPostProcessor

Instantiation:实例化,即创建出对象之前。
BeanPostProcessor的子接口,用于封装实例创建之前,之后,属性填充之前
的回调方法。通常用于替换默认的创建实例的方式(e.g 创建需要特殊目标源的对象,池对象,不同创建策略的对象)

Typically used to suppress default instantiation for specific target beans, for example to create proxies with special TargetSources (pooling targets,* lazily initializing targets, etc), or to implement additional injection strategies such as field injection.

  1. postProcessBeforeInstantiation()
    在目标bean创建 实例之前 执行,返回 bean 用于替换目标bean。如果返回了一个非null对象,后续只执行postProcessAfterInitialization(),因为此方法要求返回一个bean,而非对象

Apply this BeanPostProcessor before the target bean gets
instantiated. The returned bean object may be a proxy to use instead of the target bean, effectively suppressing default instantiation of the target bean.If a non-null object is returned by this method, the
bean creation process will be short-circuited. The only further processing applied is the postProcessAfterInitialization callback from the configured.

  1. postProcessAfterInstantiation()
    通过构造方法或者@Bean的方法创建实例之后,属性填充之前执行,通过此方法来判断是否需要进行属性注入,如果返回false,则不执行属性注入。

  2. postProcessProperties()
    在BeanFactory使用之前处理bean的属性。检查bean的属性依赖是否已经创建,也可以创建新的MutablePropertyValues来添加或删除替换属性值。

  3. postProcessPropertyValues()
    5.1开始废弃,替代者为3。

ImportAwareBeanPostProcessor
  1. postProcessBeforeInstantiation()
    如果目标bean的类实现ImportAware,则通过ImportRegistry的bean获取@Import的注解信息,注入给目标bean。

  2. postProcessProperties()
    如果目标bean是Full模式下的代理类,将BeanFactory注入给目标bean。

CommonAnnotationBeanPostProcesspor
  1. postProcessProperties()
    完成@Resource,@WebServiceRef,@EJB标记的属性注入或者方法形参注入并执行。
AutowiredAnnotationBeanPostProcessor
  1. postProcessProperties()
    完成@Autowired,@Value标记的属性注入或者方法形参的注入并执行。
SmartInstantiationAwareBeanPostProcessor

继承InstantiationAwareBeanPostProcessor,添加了用于推断bean的最终类型的回调方法,这是一个特殊的接口,用于框架的内部

  1. predictBeanType()
    predict: 预测
    预测最终 bean的实际类型。(e.g 代理中会使用)

  2. determineCandidateConstructors()
    决定创建bean时使用的构造方法候选者(可能存在多个)。

  3. getEarlyBeanReference()
    获取指定bean的 早期引用(即引用非完全bean),通常用于循环依赖,此方法给BeanPostProcessor一个 公开非完全初始化的bean 的机会。

返回对象会作为最终的依赖注入,所以 必须返回最终使用的实际bean

AutowiredAnnotationBeanPostProcessor
  1. determineCandidateConstructors()
    如果实例创建是通过构造方法,则会在实例创建之前决定使用的构造方法。
  • 推断规则
    首先获取创建bean对应的Class(可能是代理类)的所有构造方法,然后循环每个构造方法。注解获取会获取用户创建的Class的。
    rawCandidates:原始构造方法
    candidates:构造方法候选集合
    requiredConstructor:指定使用的
    defaultConstructor:默认的
  • 选取阶段
    1.构造方法是否被注解标记,被标记且requiredConstructor=null,candidates没有候选构造方法,则将当前构造方法赋值为指定使用的,否则requiredConstructor不为null抛出异常或者当前构造方法被标记required=true且候选集合非空则也抛出异常。被标记则一定加入候选集合。构造方法没有被标记,且为默认无参构造方法,赋值为defaultConstructor。

  • 决定阶段
    1.候选集合不为空, 并且没有找到指定使用的,则将默认的加入候选集合中,并设置候选数组为候选集合中的构造方法。
    2.原始构造方法只有一个,并且不是无参的构造方法,则设置此构造方法为候选数组。
    3.上面两种都不符合,则默认没有找到,返回没有数据的空候选数组。

MergedBeanDefinitionPostProcessor

用于合并BeanDefinition(即将BeanDefinition进行合并,现在一般没有了),spring使用此类 完成bean的实例(并非bean)的创建

  1. postProcessMergedBeanDefinition()
    用于合并BeanDefinition, 缓存一些 元数据(e.g 需要显示注入的属性和方法参数)

  2. resetBeanDefinition()
    5.1开始,可以用于注册BeanDefinition。

InitDestoryAnnotationBeanPostProcessor(没有直接调用)

解析@PostConstruct,@PreDestroy标记的回调方法,并后续执行,回调回调方法注解应用于可见的方法,并且可以存在多个。

  1. postProcessMergedBeanDefinition()
    解析注解标记的回调方法,并存入到Map缓存lifecycleMetadataCache

注意,回调方法 不区分是否static ,并且会递归查找父类的方法,直到没有父类,或者为Object

CommonAnnotationBeanPostProcessor

并非直接实现MergedBeanDefinitionPostProcessor而是继承InitDestoryAnnotationBeanPostProcessor.
spring用于支持JAVA注解的处理器,@Resource用于根据name进行属性注入,如果当前环境支持@WebServiceRef,@EJB并解析这些注解。

  1. postProcessMergedBeanDefinition()
    调用父类方法完成回调方法的扫描。本身解析@Resource标记的属性和方法,如果支持则解析@WebServiceRef,@EJB标记的属性和方法,并存入Map缓存injectionMetadataCache中。

@Resource,@WebServiceRef,@EJB不支持 static 属性和方法,标记会直接抛出异常。
@Resource,@WebServiceRef,@EJB方法 有且仅有一个参数
@Resource标记的属性和方法,如果类型被标记忽略,则不会进行解析缓存

AutowiredAnnotationBeanPostProcessor

用于解析@Autowired,@Value标记的属性,方法,如果环境支持的话同时也用于支持JSR-330的@Inject。

  1. postProcessMergedBeanDefinition()
    用于解析@Autowired,@Value标记的属性和方法,并存入Map缓存injectionMetadataCache中。

@Autowired,@Value,@Inject不支持 static 属性和方法,但 不会抛出异常

ApplicationListenerDetector
  1. postProcessMergedBeanDefinition()
    如果bean的实际类型是ApplicationListener,则会存入Map缓存singletonNames(beanName,是否单例)。
上一篇:spring中BeanPostProcessor 实现策略模式


下一篇:Spring中Bean的生命周期