BeanPostProcessor译为bean的后置处理器,针对某个bean的加工处理。
首先要说一下spring object != spring bean 很多人可能会说,bean不就是object吗?这么说没错,但是反过来说object是bean就不一定对了 spring object 需要通过工厂一系列的加工之后才是形成最终的spring bean,spring bean是具有完整功能及属性的对象。 这里推荐子路老师的《spring循环引用》,重点讲述了spring bean的产生过程以及依赖注入的循环引用问题。
简单看一下@Autowired注解实现类org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor的Diagram图:
官方译文:
BeanPostProcessor的子接口,它添加实例化前的回调,以及实例化后但在显式属性设置或自动装配发生之前的回调。通常用于抑制特定目标bean的默认实例化,例如创建具有特殊目标源(池目标、延迟初始化目标等)的代理,或者实现额外的注入策略,如字段注入。注意:此接口为专用接口,主要用于框架内部使用。建议尽可能实现普通的BeanPostProcessor接口,或者从InstantiationAwareBeanPostProcessorAdapter派生,以便屏蔽对该接口的扩展。
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor { //这个方法用来在对象实例化前直接返回一个对象(如代理对象)来代替通过内置的实例化流程创建对象; @Nullable default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { return null; } //在对象实例化完毕执行populateBean之前 如果返回false则spring不再对对应的bean实例进行自动依赖注入。 default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException { return true; } //这里是在spring处理完默认的成员属性,应用到指定的bean之前进行回调,可以用来检查和修改属性,最终返回的PropertyValues会应用到bean中 //@Autowired、@Resource等就是根据这个回调来实现最终注入依赖的属性的。 @Nullable default PropertyValues postProcessPropertyValues( PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException { return pvs; } }官方译文:
SmartInstantiationAwareBeanPostProcessor扩展实例化awarebeanpostprocessor 对InstantiationAwareBeanPostProcessor接口的扩展,添加了一个回调,用于预测已处理bean的最终类型。 注意:此接口为专用接口,主要用于框架内部使用。通常,应用程序提供的后处理器应该简单地实现简单的BeanPostProcessor接口或从InstantiationAwareBeanPostProcessorAdapter类派生。新方法可能会被添加到这个接口中,甚至在发布版本中。
public interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor { //用来返回目标对象的类型(比如代理对象通过raw class获取proxy type 用于类型匹配) @Nullable default Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException { return null; } //这里提供一个拓展点用来解析获取用来实例化的构造器(比如未通过bean定义构造器以及参数的情况下,会根据这个回调来确定构造器) @Nullable default Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName) throws BeansException { return null; } //获取要提前暴露的bean的引用,用来支持单例对象的循环引用(一般是bean自身,如果是代理对象则需要取用代理引用) default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException { return bean; } }官方译文:
运行时合并bean定义的后处理器回调接口。BeanPostProcessor实现可以实现这个子接口,以便对合并的bean定义(原始bean定义的处理副本)进行后期处理,Spring BeanFactory使用该定义创建一个bean实例。postProcessMergedBeanDefinition (org.springframework.beans.factory.support。例如,为了在后处理bean的实际实例之前准备一些缓存的元数据,方法可以内省bean定义。它还允许修改bean定义,但只允许修改实际上用于并发修改的定义属性。本质上,这只适用于在RootBeanDefinition本身上定义的操作,而不适用于其基类的属性。
public interface MergedBeanDefinitionPostProcessor extends BeanPostProcessor { //在bean实例化完毕后调用 可以用来修改merged BeanDefinition的一些properties 或者用来给后续回调中缓存一些meta信息使用 //这个算是将merged BeanDefinition暴露出来的一个回调 void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName); }上述资源部分来自https://www.cnblogs.com/zhangjianbin/p/10059191.html
官方译文:
Ordered是一个可以由应该是可排序的对象(例如在集合中)实现的接口。实际的顺序可以解释为优先级,第一个对象(具有最低的顺序值)具有最高的优先级。注意这个接口还有一个优先级标记:PriorityOrdered。优先排序对象表示的顺序值总是应用在普通排序对象表示的相同顺序值之前。有关非有序对象的排序语义的详细信息,请参阅OrderComparator的Javadoc
在类org.springframework.beans.factory.support.AbstractBeanFactory中有这样一个属性: 意思是在createBean方法时需要的后置处理器。我们可以看到它是个List,那么我们先关注它的add和使用。 org.springframework.beans.factory.support.AbstractBeanFactory#addBeanPostProcessor这里是对后置处理器的一个add操作,通过debug我们跟踪到两处调用: 在org.springframework.context.support.AbstractApplicationContext#refresh方法中 首先会在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation中调用,包括对对象是否需要代理进行处理(org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessBeforeInstantiation中判断,如果不需要代理会将对象放入一个容器中,value为false当然这不是我讲的重点,顺带提一下),
使用示例:
import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.stereotype.Component; @Component public class MyProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if(beanName.equals("testProcessor")){ System.out.println(beanName + "----postProcessBeforeInitialization"); } return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if(beanName.equals("testProcessor")){ System.out.println(beanName + "----postProcessAfterInitialization"); } return bean; } } import com.platform.mst.helper.replacecomponent.TestService; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component public class TestProcessor implements InitializingBean { @Autowired private TestService service; public TestProcessor() { System.out.println("com.platform.mst.helper.processor.TestProcessor.TestProcessor"); } @Override public void afterPropertiesSet() throws Exception { System.out.println("com.platform.mst.helper.processor.TestProcessor.afterPropertiesSet"); } }其中的"testService-----"打印是TestService构造器中打印的,在对TestProcessor进入属性注入的时候会从容器中获取,如果没有就会对属性类型进行初始化、加工…等等操作最终set,这里不做详细说明。
感觉东西太多了,先写个大概。。。。。未完!!!