(五)關於BeanPostProcessor各個回撥的時機
阿新 • • 發佈:2019-01-10
1、BeanPostProcessor的五大介面
一共有11個回撥方法
1.1.BeanPostProcessor
關於物件初始化前後的回撥。
public interface BeanPostProcessor {
//該方法在bean例項化完畢(且已經注入完畢),在afterPropertiesSet或自定義init方法執行之前
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
//在afterPropertiesSet或自定義init方法執行之後
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
1.2.InstantiationAwareBeanPostProcessor
關於物件例項化前後以及例項化後設置propertyValues的回撥
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;
}
}
1.3.SmartInstantiationAwareBeanPostProcessor
這個介面主要是spring框架內部來使用
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;
}
}
1.4.MergedBeanDefinitionPostProcessor
用來將merged BeanDefinition暴露出來的回撥
public interface MergedBeanDefinitionPostProcessor extends BeanPostProcessor {
//在bean例項化完畢後呼叫 可以用來修改merged BeanDefinition的一些properties 或者用來給後續回撥中快取一些meta資訊使用
//這個算是將merged BeanDefinition暴露出來的一個回撥
void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName);
}
1.5.DestructionAwareBeanPostProcessor
關於處理物件銷燬的前置回撥
應用例項:
ApplicationListenerDetector,這個類是用來註冊ApplicationListener例項的,而如果銷燬一個物件,不接觸這裡的引用
會導致無法進行回收,因此在銷燬物件時,會判斷如果是ApplicationListener要執行從監聽器列表中移除掉。
public interface DestructionAwareBeanPostProcessor extends BeanPostProcessor {
//這裡實現銷燬物件的邏輯
void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException;
//判斷是否需要處理這個物件的銷燬
default boolean requiresDestruction(Object bean) {
return true;
}
}
2.關於BeanPostProcessor中各個回撥呼叫的順序
1、InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation(beanClass, beanName)
該方法在建立物件之前會先掉用,如果有返回例項則直接使用不會去走下面建立物件的邏輯,並在之後執行
BeanPostProcessor.postProcessAfterInitialization(result, beanName)
2、SmartInstantiationAwareBeanPostProcessor.determineCandidateConstructors(beanClass, beanName)
如果需要的話,會在例項化物件之前執行
3、MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition(mbd, beanType, beanName)
在物件例項化完畢 初始化之前執行
4、InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)
在bean建立完畢初始化之前執行
5、InstantiationAwareBeanPostProcessor.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName)
在bean的property屬性注入完畢 向bean中設定屬性之前執行
6、BeanPostProcessor.postProcessBeforeInitialization(result, beanName)
在bean初始化(自定義init或者是實現了InitializingBean.afterPropertiesSet())之前執行
7、BeanPostProcessor.postProcessAfterInitialization(result, beanName)
在bean初始化(自定義init或者是實現了InitializingBean.afterPropertiesSet())之後執行
8、其中DestructionAwareBeanPostProcessor方法的postProcessBeforeDestruction(Object bean, String beanName)會在銷燬物件前執行
DestructionAwareBeanPostProcessor 中的requiresDestruction(Object bean)是用來判斷是否屬於當前processor處理的bean
SmartInstantiationAwareBeanPostProcessor中的predictBeanType(Class<?> beanClass, String beanName)是用來預判型別的
SmartInstantiationAwareBeanPostProcessor.getEarlyBeanReference(exposedObject, beanName)
這個方法僅僅是在這一步是作為一個ObjectFactory封裝起來放到singletonFactories中的,
僅在併發情況下 剛好在當前物件設定進去,而另一個bean建立需要getBean獲取時才會立即執行
因此這一步的順序是不一定的,有可能永遠不會執行(無併發循壞依賴物件建立的場景)
可能在3之後物件例項化完畢執行addSingleton(beanName, singletonObject);之前執行到
因此這三個方法沒有嚴格的順序意義
3.驗證執行順序
@Configuration
public class Application {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Application.class);
applicationContext.registerBeanDefinition("demoBean", new RootBeanDefinition(DemoBean.class));
applicationContext.getBean("demoBean");
applicationContext.start();
applicationContext.destroy();
}
@Bean
public BeanPostProcessor fullyPostProcessor() {
return new FullyBeanPostProcessor();
}
public static class DemoBean {
}
@Order
public class FullyBeanPostProcessor implements BeanPostProcessor,
InstantiationAwareBeanPostProcessor,
SmartInstantiationAwareBeanPostProcessor,
MergedBeanDefinitionPostProcessor,
DestructionAwareBeanPostProcessor {
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
if (beanClass == DemoBean.class) {
System.out.println("1 --> InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation(beanClass, beanName)");
}
return null;
}
@Override
public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName) throws BeansException {
if (beanClass == DemoBean.class) {
System.out.println("2 --> SmartInstantiationAwareBeanPostProcessor.determineCandidateConstructors(beanClass, beanName)");
}
return null;
}
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
if (beanType == DemoBean.class) {
System.out.println("3 --> MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition(mbd, beanType, beanName)");
}
}
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
if (bean instanceof DemoBean) {
System.out.println("4 --> InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)");
}
return true;
}
@Override
public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
if (bean instanceof DemoBean) {
System.out.println("5 --> InstantiationAwareBeanPostProcessor.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName)");
}
return pvs;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof DemoBean) {
System.out.println("6 --> BeanPostProcessor.postProcessBeforeInitialization(result, beanName)");
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof DemoBean) {
System.out.println("7 --> BeanPostProcessor.postProcessAfterInitialization(result, beanName)");
}
return bean;
}
@Override
public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
if (bean instanceof DemoBean) {
System.out.println("8 --> DestructionAwareBeanPostProcessor.postProcessBeforeDestruction(Object bean, String beanName)");
}
}
@Override
public Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {
return null;
}
@Override
public Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
return bean;
}
}
}
最終輸出結果:
1 --> InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation(beanClass, beanName)
2 --> SmartInstantiationAwareBeanPostProcessor.determineCandidateConstructors(beanClass, beanName)
3 --> MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition(mbd, beanType, beanName)
4 --> InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)
5 --> InstantiationAwareBeanPostProcessor.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName)
6 --> BeanPostProcessor.postProcessBeforeInitialization(result, beanName)
7 --> BeanPostProcessor.postProcessAfterInitialization(result, beanName)
8 --> DestructionAwareBeanPostProcessor.postProcessBeforeDestruction(Object bean, String beanName)