BeanPostProcessor接口作用是:如果需要在Spring容器完成Bean的实例化、配置和其他的初始化前后添加一些自定义的逻辑处理,就可以通过定义一个或者多个BeanPostProcessor接口的实现,然后注册到容器中。实质上,BeanPostProcessor是spring bean加载过程中的回调接口。
Spring中Bean的实例化过程图示:
1. 有哪些后处理器
1.1 具体类
1. AutowiredAnnotationBeanPostProcessor
作用:当 Spring 容器启动时,AutowiredAnnotationBeanPostProcessor 将扫描Spring容器中所有 Bean,当发现
Bean 中拥有 @Autowired 注释时就找到和其匹配(默认按类型匹配)的 Bean,并注入到对应的地方中去。
2. InitDestroyAnnotationBeanPostProcessor
作用:bean初始化、销毁方法扫描执行
3. RequiredAnnotationBeanPostProcessor
作用:bean的属性字段的注入值扫描检查
1.2 接口类:
1.DestructionAwareBeanPostProcessor
2.MergedBeanDefinitionPostProcessor
4.InstantiationAwareBeanPostProcessor
5.SmartInstantiationAwareBeanPostProcessor
1.3 后处理器适配器
InstantiationAwareBeanPostProcessorAdapter
InstantiationAwareBeanPostProcessorAdapter将SmartInstantiationAwareBeanPostProcessor上的所有方法实现为no-ops的适配器,它不会更改容器实例化的每个bean的正常处理(源码中没有具体的操作,直接返回)。 子类可以仅覆盖它们实际感兴趣的那些方法。
注意:仅当需要InstantiationAwareBeanPostProcessor功能时,才建议使用此基类。 如果只需要简单的BeanPostProcessor功能,则直接实现BeanPostProcessor接口即可
2. beanPostProcessor相关子类介绍
1). 若bean有一个被’@required’标注的构造函数,表示这个构造函数是这个bean类在Spring bean自动装配时的构造函数。
2). 若bean有多个构造函数带有注释,则为它们将被视为spring bean自动装配的候选构造函数。将选择具有最大数量的依赖项的构造函数,这些构造函数可以通过匹配Spring容器中的bean来满足。
3). 若bean没有候选构造函数可以满足,然后将使用默认构造函数(如果存在)
4). 带注释的构造函数不必是公共的。
当bean调用构造函数后,然后立即对字段进行依赖注入, 其次是config(例如@postConstruct 方法)方法调用。这样的配置字段不必是public的。
1)bean 的config配置方法不限定名称和参数数量;
2)config方法的每个参数将与Spring容器中的匹配bean一起自动装配;
3)bean的字段属性的setter方法实际上是spring config方法的特殊场景使用;
4)config方法不必是public的;
2.1 AutowiredAnnotationBeanPostProcessor 注解后处理器介绍
AutowiredAnnotationBeanPostProcessor实现自动装配带注释的字段,setter方法和任意配置方法。通过Spring的@Autowired和@Value注释,同时还支持JSR-330的@Inject注释。
使用方式:通过“<context:annotation-config>”或者“<context:component-scan>”XML标签注册一个默认的AutowiredAnnotationBeanPostProcessor;同时也可以不使用默认配置,采用自定义的AutowiredAnnotationBeanPostProcessor来处理spring bean的bean definition扫描工作。
注意:注释注入将在 XML注入之前执行; 因此xml配置将覆盖前者的属性连接。
除了如上所述的常规注入点之外,AutowiredAnnotationBeanPostProcessor还处理Spring的@Lookup注释,用于标识查找在运行时由容器替换的方法。例如:spring容器中替换getBean(Class,args)和getBean(String,args)者两个方法。
AutowiredAnnotationBeanPostProcessor 类图关系如下:
2.2 InitDestroyAnnotationBeanPostProcessor 注解初始化\销毁bean后处理器
spring 容器在bean装载过程中,实现bean类初始化方法回调方式有三种:
Constructor > @PostConstruct > InitializingBean > init-method
1)对init和destroy方法加必要的注释(如:@PostConstruct/@PreDestroy) --- 优先执行
2)bean类实现InitializingBean和DisposableBean回调接口类(实现afterPropertiesSet方法即可)-- 其次执行
3)bean的xml中配置init-method属性标签---最后执行
可以通过“initAnnotationType”和“destroyAnnotationType”属性配置此后处理器检查的实际注释类型(就是@PostConstruct/@PreDestroy)),也可以使用任何自定义注释。
初始化和销毁注释可以应用于任何可见性的方法:公共,包受保护,受保护或私有。 可以注释多个这样的方法,但是建议一个bean类中分别仅注释一个单个init方法和destroy方法。
Spring的CommonAnnotationBeanPostProcessor分别支持开箱即用的JSR-250 PostConstruct和PreDestroy注释,作为init注释和销毁注释。 此外,它还支持注释驱动注入命名bean的Resource注释。
InitDestroyAnnotationBeanPostProcessor类图如下:
2.3 RequiredAnnotationBeanPostProcessor依赖bean检查的bean后处理器
在spring容器bean装载中,通过Spring的Required注释来强制配置所需的一个JavaBean属性。
1)一个类中的被注解的(setter) 方法必须配置一个用来依赖注入的值
2)@Required 只能加到bean中字段的setter方法上
3)RequiredAnnotationBeanPostProcessor仅检查值是否存在,不进行依赖注入
存在RequiredAnnotationBeanPostProcessor的动机是允许开发人员使用任意JDK 1.5注释来注释其自己的类的setter属性,以指示spring容器必须检查依赖注入值的配置。将这种检查的责任推到了容器上,并且不需要开发人员编写一个方法来简单地检查所有必需的属性是否已经实际设置。
注意:RequiredAnnotationBeanPostProcessor仅仅检查配置了“required”的字段属性的值是否注入(存在),但不会检查配置的值是否为NULL。
使用方式:通过在xml中配置“<context:annotation-config>”和“<context:component-scan>”XML标签来引入注册一个默认RequiredAnnotationBeanPostProcessor。也可以自定义配置一个RequiredAnnotationBeanPostProcessor,同样需要删除或者关闭默认配置。
<bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor">
<property name="requiredAnnotationType" value="your.company.package.Mandatory"/>
</bean>
// Mandatory 如下;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Mandatory {
}
RequiredAnnotationBeanPostProcessor类图如下:
2.4 CommonAnnotationBeanPostProcessor注解方法的bean后处理器
特性:
1)支持@PostConstruct、@PreDestroy
2)优先级值:LOWEST_PRECEDENCE-3-- 值越大优先级越小
3.后处理器接口类介绍
3.1 BeanPostProcessor
BeanPostProcessor是bean装载过程中的一个工厂钩子类,是一个回调函数。
1)ApplicationContexts自动检测相关BeanPostProcessor,并实例化,进而应用于随后普通bean创建。
2)普通bean工厂对BeanPostProcessor进行程序化注册,并用于后续该工厂所有bean的创建
接口方法:
1)postProcessBeforeInitialization(Object bean, String beanName)
a) 此时bean实例完成了bean属性填充、但未调用初始化方法(如InitializingBean的afterPropertiesSet或自定义init方法)
b) 若bean是一个FactoryBean,则该回调方法可能被FactoryBean实例或者FactoryBean创建的实例对象调用
c)返回的bean实例可能是原始实例的包装器。
2)postProcessAfterInitialization(Object bean, String beanName)
a) 此时bean实例完成了bean属性填充、同时完成初始化方法(如InitializingBean的afterPropertiesSet或自定义init方法)调用
b) 若bean是一个FactoryBean,则该回调方法可能被FactoryBean实例或者FactoryBean创建的实例对象调用
c)在InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation方法触发后也会调用该回调方法
d)返回的bean实例可能是原始实例的包装器。
3.2 InstantiationAwareBeanPostProcessor
在显式属性设置或自动装配发生之前 添加了的实例化前回调操作和实例化后回调操作。
3.3 SmartInstantiationAwareBeanPostProcessor
扩展InstantiationAwareBeanPostProcessor接口,添加一个回调以预测已处理bean的最终类型。
1)predictBeanType(): 预测给定bean类的最终类型
2)determineCandidateConstructors(): 获取bean的所有构造函数
3)getEarlyBeanReference(): 获取指定bean的早起(未实例化之前)引用,解决循环应用问题
3.4 MergedBeanDefinitionPostProcessor
postProcessMergedBeanDefinition 方法可以内省bean定义,以便在后处理bean的实际实例之前准备一些缓存的元数据。
a) 合并的bean定义是原始bean定义的副本
b)允许修改bean定义,但仅限于实际用于并发修改的定义属性, 实质上仅适用于RootBeanDefinition本身定义的操作,不适用于其基类的属性
void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName);
对指定bean的进行给定的合并bean定义后处理。