PostProcessor
為什么要有這個(gè)后置處理器這種接口,了解Spring容器的朋友應(yīng)該知道,所有的ApplicationContext都需要調(diào)用AbstractApplicationContext#refresh方法,這是一個(gè)模板方法,既然使用了模板方法設(shè)計(jì)模式,那么就應(yīng)該提供hook,也就是鉤子函數(shù)。而PostProcessor就是為了實(shí)現(xiàn)這種定制化的擴(kuò)展需求而制定的。
UML
-
BeanPostProcessor
BeanPostProcessor -
BeanFactoryPostProcessor
BeanFactoryPostProcessor
PostProcessor概覽
BeanFactoryPostProcessor
容器級(jí)別的后置處理器,其內(nèi)部僅聲明了一個(gè)方法。Spring會(huì)根據(jù)聲明的順序?qū)笾锰幚砥鬟M(jìn)行調(diào)用,而BeanFactoryPostProcessor會(huì)在容器初始化期間將容器本身交由接口實(shí)現(xiàn)類去處理。獲取到了容器,就可以做很多定制化的操作了。
@FunctionalInterface
public interface BeanFactoryPostProcessor {
/**
* Modify the application context's internal bean factory after its standard
* initialization. All bean definitions will have been loaded, but no beans
* will have been instantiated yet. This allows for overriding or adding
* properties even to eager-initializing beans.
* @param beanFactory the bean factory used by the application context
* @throws org.springframework.beans.BeansException in case of errors
*/
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
BeanDefinitionRegistryPostProcessor
從注解容器解析BeanDefinition的篇章中,你會(huì)了解到
BeanDefinitionRegistryPostProcessor是一種特殊的BeanFactoryPostProcessor,但是Spring會(huì)優(yōu)先處理這類后置處理器,再處理常規(guī)的一些BeanFactoryPostProcessor.可以理解成VIP級(jí)別的BeanFactoryPostProcessor,優(yōu)先于常規(guī)BeanFactoryPostProcessor執(zhí)行。
其內(nèi)部也聲明了一個(gè)專用的注冊(cè)后置處理方法。postProcessBeanDefinitionRegistry
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
/**
* Modify the application context's internal bean definition registry after its
* standard initialization. All regular bean definitions will have been loaded,
* but no beans will have been instantiated yet. This allows for adding further
* bean definitions before the next post-processing phase kicks in.
* @param registry the bean definition registry used by the application context
* @throws org.springframework.beans.BeansException in case of errors
*/
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
}
BeanPostProcessor
容器創(chuàng)建Bean時(shí)的hook實(shí)例,你可以通過實(shí)現(xiàn)BeanPostProcessor來影響所有Bean的生命周期,包括
Initialization的前置與后置處理.在后面學(xué)習(xí)Spring Bean的生命周期中,會(huì)接觸BeanPostProcessor
public interface BeanPostProcessor {
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
使用postProcessor
MyBeanFactoryPostProcessor
- 基礎(chǔ)對(duì)象
@Data
public class Root {
private String name;
private String description;
private boolean isRoot;
}
- 通過后置處理器往容器注入BeanDefinition
package com.xjm.bean.postprocessor;
import com.xjm.model.Root;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.*;
import org.springframework.context.annotation.Configuration;
/**
* @author jaymin
* 2021/1/7 23:10
*/
@Configuration
public class MyBeanFactoryPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
}
/**
* 標(biāo)準(zhǔn)初始化后,修改應(yīng)用程序上下文的內(nèi)部BeanDefiniton注冊(cè)表。<br>
* 所有常規(guī)bean定義都將被加載,但尚未實(shí)例化任何bean。 <br>
* 這允許在下一個(gè)后處理階段開始之前添加更多的BeanDeinition。 <br>
* Spring工廠級(jí)別的BeanFactoryPostProcessor,優(yōu)先級(jí)別高于常規(guī)的BeanFactoryPostProcessor.<br>
* 第三方框架整合時(shí),可以實(shí)現(xiàn)這個(gè)注冊(cè)接口進(jìn)行BeanDefinition注冊(cè).如Mybatis.<br>
* 設(shè)計(jì)模式:責(zé)任鏈模式<br>
* @param registry the bean definition registry used by the application context
* @throws BeansException
*/
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
BeanDefinition beanDefinition = getBeanDefinition(Root.class);
registry.registerBeanDefinition("root",beanDefinition);
System.out.println("Customer BeanPostProcessors execute.");
}
private BeanDefinition getBeanDefinition(Class<?> clazz){
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(clazz).getBeanDefinition();
return beanDefinition;
}
}
- test
@ComponentScan根據(jù)自己的包路徑進(jìn)行修改,此處程序正常運(yùn)行,說明Root已經(jīng)注冊(cè)到容器中了.
@Configuration
@ComponentScan(value = "com.xjm")
public class BeanDefinitionDemoByAnnotation {
public static void main(String[] args) {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AnnotationContextDemo.class);
Root root = applicationContext.getBean("root", Root.class);
}
}
MyBeanPostProcessor
簡(jiǎn)單實(shí)現(xiàn)BeanPostProcessor,主要是觀察其行為的作用域.
@Configuration
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
@Nullable
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println(beanName + " invoking MyBeanPostProcessor#postProcessBeforeInitialization");
return bean;
}
/**
* 可以對(duì)所有的Bean做統(tǒng)一操作
* @param bean the new bean instance
* @param beanName the name of the bean
* @return
* @throws BeansException
*/
@Override
@Nullable
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println(beanName + " invoking MyBeanPostProcessor#postProcessAfterInitialization");
return bean;
}
}
- result

可以看到,實(shí)現(xiàn)的MyBeanPostProcessor影響了所有Bean的初始化過程.
總結(jié)
- 后置處理器是Spring留給開發(fā)者的擴(kuò)展性鉤子接口。
- 從后置處理器上可以簡(jiǎn)略分為:
BeanFactoryPostProcessor和BeanPostProcessor.其中,BeanFactoryPostProcessor可以操作容器,BeanPostProcessor會(huì)影響所有Bean的生命周期. -
BeanDefinitionRegistryPostProcessor是一種特殊的BeanFactoryPostProcessor,優(yōu)于其他BeanFactoryPostProcessor執(zhí)行.
擴(kuò)展閱讀
Spring系列六:Spring BeanPostProcessor
談?wù)凷pring中的BeanPostProcessor接口
Spring 執(zhí)行順序:PostProcessor 接口
Spring BeanPostProcessor

