BeanFactoryPostProcessor BeanPostProcessor java doc解读


传送:

Spring大观园,我有过的困惑或许你也有!


概述
  • BeanFactoryPostProcessor 往beanFactory中 添加、修改bean 的定义信息
  • BeanPostProcessor 修改bean实例信息
BeanFactoryPostProcessor 在往应用上下文(容器)里放置bean的定义信息的流程中,发挥一些添加更改bean的定义的作用。
  • java doc

工厂挂钩允许采用bean工厂上下文 中 bean 属性的值,对应用程序上下文的bean定义进行自定义修改,
系统管理员通过在自定义配置文件中配置的bean属性,覆盖应用程序上下文中Bean的属性。请参阅PropertyResourceConfigurer及其具体实现,以获取可解决此类配置需求的即用型解决方案。PropertyPlaceholderConfigurer读取配置文件
BeanFactoryPostProcessor可以与Bean定义进行交互并对其进行修改,但不能与Bean实例进行交互。这样做可能会导致bean实例化过早,从而违反了容器并造成了意外的副作用。如果需要与bean实例交互,请考虑实现BeanPostProcessor。
注册
ApplicationContext在其Bean定义中自动检测BeanFactoryPostProcessor Bean,并在创建任何其他Bean之前应用它们。 BeanFactoryPostProcessor也可以通过编程方式注册到ConfigurableApplicationContext。
定购
将根据org.springframework.core.PriorityOrdered和org.springframework.core.Ordered语义对在ApplicationContext中自动检测到的BeanFactoryPostProcessor bean进行排序。相反,通过ConfigurableApplicationContext以编程方式注册的BeanFactoryPostProcessor Bean将按注册顺序应用;以编程方式注册的后处理器将忽略通过实现PriorityOrdered或Ordered接口表示的任何排序语义。此外,BeanFactoryPostProcessor Bean不考虑@Order批注

  • 总结:
    先用BeanFactoryPostProcessor处理了bean的定义后,才会创建bean;
    ApplicationContext创建BeanFactoryPostProcessor 分两种情况:
    1. 从bean定义中找到,排序后注册,排序优先级PriorityOrdered> Ordered,BeanFactoryPostProcessor的排序忽略@Order注解。
    2. 编程方式直接实例化注册,按照代码注册顺序排序。
BeanDefinitionRegistryPostProcessor

BeanFactoryPostProcessor的实现 提供void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)方法 用于注册BeanDefinition。因为继承其同时还有 postProcessBeanFactory方法。
BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistryBeanFactoryPostProcessor#postProcessBeanFactory 都可以注册BeanDefinition的区别是,前者执行时机早于后者,而且从名字上前者更明确了他的postProcessBeanDefinitionRegistry是用来注册BeanDefinition,那是不是考虑BeanFactoryPostProcessor中只做修改BeanDefinition

核心方法 postProcessBeanFactory & postProcessBeanDefinitionRegistry
  1. bean 工厂已经被初始化了
  2. 通过postProcessBeanDefinitionRegistry 往工厂中注册 BeanDefinition
  3. bean 的定义都被加载到工厂中,但是bean 都没被初始化
  4. 执行postProcessBeanFactory,此时对bean工厂操作,可以修改bean的定义
  5. 经过一些步骤后... bean会被初始化,bean的初始化涉及到BeanPostProcessor
BeanPostProcessor 根据bean的定义在创建bean的一些流程中发挥作用。

1.实例化bean,属性注入
2.执行 BeanPostProcessor#postProcessBeforeInitialization
3.如果有,执行InitializingBean#afterPropertiesSet
4.如果有,执行自定义init-method 如:@Bean(name = "person",initMethod = "xxx")
5.执行 BeanPostProcessor#postProcessAfterInitialization

Factory hook that allows for custom modification of new bean instances, e.g. checking for marker interfaces or wrapping them with proxies.
beanFactory提供了钩子,在 new bean的实例时候,通过钩子方法,我们可以对bean做一些手脚;比如一些marker interfaces(没有方法的接口)的校验,或者通过代理的方式增强bean。
ApplicationContexts can autodetect BeanPostProcessor beans in their bean definitions and apply them to any beans subsequently created. Plain bean factories allow for programmatic registration of post-processors, applying to all beans created through this factory.
三层意思:
1.一个可以通过编程的方式直接向bean工厂中注册BeanPostProcessor,那bean工厂所创建的所有的bean,都会经历这些已注册的BeanPostProcessor的逻辑处理。
2.ApplicationContexts 随着bean的解析加载的推进,能够从bean definitions 识别出更多的BeanPostProcessor类型的beans;
3.一旦发现新的BeanPostProcessor,再有新的bean的创建时,这个BeanPostProcessor就要干活。
Typically, post-processors that populate beans via marker interfaces or the like will implement postProcessBeforeInitialization, while post-processors that wrap beans with proxies will normally implement postProcessAfterInitialization.
那些通过接口或者注解来装配beans的post-processors,都会实现postProcessBeforeInitialization方法,而对bean的增强操作都在postProcessAfterInitialization方法中来实现。

public interface BeanPostProcessor {  
  
    /** 
     * Apply this BeanPostProcessor to the given new bean instance before any bean 
     * initialization callbacks (like InitializingBean's {@code afterPropertiesSet} 
     * or a custom init-method). The bean will already be populated with property values.    
     */  
    //实例化、依赖注入(属性装配)完毕,在调用显式的初始化之前完成一些定制的初始化任务  
    //org.springframework.beans.factory.InitializingBean#afterPropertiesSet,
    //自定义init-method 如:@Bean(name = "person",initMethod = "xxx")
    Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;  
  
      
        /**
     * Apply this {@code BeanPostProcessor} to the given new bean instance after any bean
     * initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
     * or a custom init-method). The bean will already be populated with property values.
     * The returned bean instance may be a wrapper around the original.
     * 

In case of a FactoryBean, this callback will be invoked for both the FactoryBean * instance and the objects created by the FactoryBean (as of Spring 2.0). The * post-processor can decide whether to apply to either the FactoryBean or created * objects or both through corresponding {@code bean instanceof FactoryBean} checks. *

This callback will also be invoked after a short-circuiting triggered by a * {@link InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation} method, * in contrast to all other {@code BeanPostProcessor} callbacks. *

The default implementation returns the given {@code bean} as-is. * @param bean the new bean instance * @param beanName the name of the bean * @return the bean instance to use, either the original or a wrapped one; * if {@code null}, no subsequent BeanPostProcessors will be invoked * @throws org.springframework.beans.BeansException in case of errors * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet * @see org.springframework.beans.factory.FactoryBean */ //实例化、依赖注入、初始化方法完毕时执行 //spring2.0开始对于FactoryBean,其自身以及所创建的bean,此方法都会被应用,代码中通过 bean instance of FactoryBean 来判断是factorybean 还是bean。 //InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation也能触发这个方法的调用。 Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException; }

AutowiredAnnotationBeanPostProcessor

实现,自动装配带注释的字段,setter方法和任意配置方法。 要注入的这些成员是通过Java 5注释检测的:默认情况下,Spring的@Autowired和@Value注释。
还支持JSR-330的@Inject注释(如果可用),作为Spring自己的@Autowired的直接替代品。
任何给定bean类中只有一个构造函数(最大值)可以携带此注释,并将'required'参数设置为true,表示构造函数在用作Spring bean时要自动装配。 如果多个非必需构造函数带有注释,则它们将被视为自动装配的候选者。 将选择具有最大数量依赖关系的构造函数,这些构造函数可以通过匹配Spring容器中的bean来满足。 如果不能满足任何候选者,则将使用默认构造函数(如果存在)。 带注释的构造函数不必是公共的。
在调用任何配置方法之前,在构造bean之后立即注入字段。 这样的配置字段不必是公共的。
配置方法可以有任意名称和任意数量的参数; 每个参数都将使用Spring容器中的匹配bean进行自动装配。 Bean属性setter方法实际上只是这种通用配置方法的一个特例。 配置方法不必是公开的。
注意:默认的AutowiredAnnotationBeanPostProcessor将由"context:annotation-config"和"context:component-scan"XML标记注册。 如果要指定自定义AutowiredAnnotationBeanPostProcessor bean定义,请删除或关闭默认注释配置。
注意:注释注入将在XML注入之前执行; 因此后一种配置将覆盖通过两种方法连接的属性的前者。
除了上面讨论的常规注入点之外,这个后处理器还处理Spring的@Lookup注释,该注释标识了在运行时由容器替换的查找方法。 这本质上是getBean(Class,args)和getBean(String,args)的类型安全版本,有关详细信息,请参阅@ Lookup的javadoc。

你可能感兴趣的:(BeanFactoryPostProcessor BeanPostProcessor java doc解读)