BeanFactoryPostProcessor和BeanPostProcessor
建议订阅博主专栏,从下到上系统手写spring源码,体会其中过程!
BeanFactoryPostProcessor和BeanPostProcessor是spring框架中具有重量级地位的两个接口,理解了这两个接口的作用,基本就理解spring的核心原理了。为了降低理解难度分两个小节实现。
- BeanFactoryPostProcessor是spring提供的容器扩展机制,允许我们在bean实例化之前修改bean的定义信息即BeanDefinition的信息。其重要的实现类有PropertyPlaceholderConfigurer和CustomEditorConfigurer,PropertyPlaceholderConfigurer的作用是用properties文件的配置值替换xml文件中的占位符,CustomEditorConfigurer的作用是实现类型转换。BeanFactoryPostProcessor的实现比较简单,看单元测试BeanFactoryPostProcessorAndBeanPostProcessorTest#testBeanFactoryPostProcessor追下代码。
- BeanPostProcessor也是spring提供的容器扩展机制,不同于BeanFactoryPostProcessor的是,BeanPostProcessor在bean实例化后修改bean或替换bean。BeanPostProcessor是后面实现AOP的关键。 BeanPostProcessor的两个方法分别在bean执行初始化方法(后面实现)之前和之后执行,理解其实现重点看单元测试BeanFactoryPostProcessorAndBeanPostProcessorTest#testBeanPostProcessor和AbstractAutowireCapableBeanFactory#initializeBean方法,有些地方做了微调,可不必关注。
总的来说,BeanFactoryPostProcessor是用来自定义修改BeanDefinition的属性值,而BeanPostProcessor是用于修改实例化后的Bean的修改扩展点,一个针对BeanDefinition一个针对Bean。
BeanFactoryPostProcessor
- BeanFactoryPostProcessor接口,里面提供扩展BeanDefinition的方法postProcessBeanFactory。
/**
* 允许自定义修改BeanDefinition的属性值
* @author WangChao
* @version 1.0
* @date 2023/6/25 11:06
*/
public interface BeanFactoryPostProcessor {
/**
* 在所有BeanDefintion加载完成后,但在bean实例化之前,提供修改BeanDefinition属性值的机制
* @param beanFactory
* @throws BeansException
*/
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
- 编写BeanFactoryPostProcessor的实现类CustomBeanFactoryPostProcessor,这个类是用户自定义实现的切面类,在方法中,我们可以获取名称为指定类型的BeanDefinition,然后针对其属性做增强。例子中,我们将name属性更改为ivy。
public class CustomBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
BeanDefinition person = beanFactory.getBeanDefinition("person");
PropertyValues propertyValues = person.getPropertyValues();
//将person的name属性改为ivy
propertyValues.addPropertyValue(new PropertyValue("name","ivy"));
}
}
- 测试BeanFactoryPostProcessor,由于DefaultListableBeanFactory是ConfigurableListableBeanFactory的实现类,我们将beanFactory传入postProcessBeanFactory方法中,然后测试切面是否执行成功。
@Test
public void testBeanFactoryPostProcessor() throws Exception {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
xmlBeanDefinitionReader.loadBeanDefinition("classpath:spring.xml");
//在所有BeanDefintion加载完成后,但在bean实例化之前,修改BeanDefinition的属性值
CustomBeanFactoryPostProcessor beanFactoryPostProcessor = new CustomBeanFactoryPostProcessor();
beanFactoryPostProcessor.postProcessBeanFactory(beanFactory);
Person person = (Person)beanFactory.getBean("person");
System.out.println(person.getName());
}
BeanPostProcessor
- 该接口提供了两个方法,一个在初始化之前执行,一个在初始化之后执行,这里是实现AOP的关键。
public interface BeanPostProcessor {
/**
* 在bean执行初始化方法之前执行此方法
* @param bean
* @param beanName
* @return
* @throws BeansException
*/
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
/**
* 在bean执行初始化方法之后执行此方法
* @param bean
* @param beanName
* @return
* @throws BeansException
*/
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}
- 在Bean容器中添加执行BeanPostProcessor中两个方法的对应方法(为什么要这样实现呢?这里是将外部实现和容器内部实现分离开)
public interface AutowireCapableBeanFactory extends BeanFactory {
/**
* 执行BeanPostProcessors的postProcessBeforeInitialization方法
* @param existingBean
* @param beanName
* @return
* @throws BeansException
*/
Object applyBeanPostProcessorsBeforeInitialization(Object existingBean,String beanName) throws BeansException;
/**
* 执行BeanPostProcessors的postProcessAfterInitialization方法
* @param existingBean
* @param beanName
* @return
* @throws BeansException
*/
Object applyBeanPostProcessorsAfterInitialization(Object existingBean,String beanName) throws BeansException;
}
- 在ConfigurableBeanFactory中加入方法addBeanPostProcessor,该方法用来将BeanPostProcessor加入到容器中的list中,后续需要获取这些BeanPostProcessor。
public interface ConfigurableBeanFactory extends HierarchicalBeanFactory,SingletonBeanRegistry {
/**
* 添加BeanPostProcessor
* @param beanPostProcessor
*/
void addBeanPostProcessor(BeanPostProcessor beanPostProcessor);
}
- 在AbstractBeanFactory中实现addBeanPostProcessor方法,该类中新增了beanPostProcessors这个List对象,还提供了getBeanPostProcessors方法用来获取List集合。
@Override
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
//有则覆盖
this.beanPostProcessors.remove(beanPostProcessor);
this.beanPostProcessors.add(beanPostProcessor);
}
public List<BeanPostProcessor> getBeanPostProcessors() {
return this.beanPostProcessors;
}
- 在doCreateBean方法中,调用initializeBean方法,这个方法用来执行bean的初始化和前置后置方法。在前置后置方法中,通过获取list集合中的BeanPostProcessor对象,来执行对象中postProcessBeforeInitialization和After方法。
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
private InstantiationStrategy instantiationStrategy = new SimpleInstantiationStrategy();
@Override
protected Object createBean(String beanName, BeanDefinition beanDefinition) throws BeansException{
return doCreateBean(beanName,beanDefinition);
}
/**
* 创建bean示例
* @param beanName
* @param beanDefinition
* @return
* @throws BeansException
*/
protected Object doCreateBean(String beanName,BeanDefinition beanDefinition) throws BeansException{
Object bean;
try{
bean = createBeanInstance(beanDefinition);
//为bean填充属性
applyPropertyValues(beanName,bean,beanDefinition);
//执行bean的初始化方法和BeanPostProcessor的前置和后置处理方法
bean = initializeBean(beanName,bean,beanDefinition);
} catch (Exception e) {
throw new BeansException("Instantiation of bean failed", e);
}
addSingleton(beanName,bean);
return bean;
}
/**
* 利用实例化策略创建对象
* @param beanDefinition
* @return
*/
protected Object createBeanInstance(BeanDefinition beanDefinition){
return getInstantiationStrategy().instantiate(beanDefinition);
}
/**
* 给bean对象注入属性
* @param beanName
* @param bean
* @param beanDefinition
*/
protected void applyPropertyValues(String beanName,Object bean,BeanDefinition beanDefinition){
try{
for(PropertyValue propertyValue:beanDefinition.getPropertyValues().getPropertyValues()){
String name = propertyValue.getName();
Object value = propertyValue.getValue();
if(value instanceof BeanReference){
BeanReference beanReference = (BeanReference)value;
value = getBean(beanReference.getBeanName());
}
//通过反射设置属性
BeanUtil.setFieldValue(bean,name,value);
}
}catch (Exception e){
throw new BeansException("Error setting property values for bean: " + beanName, e);
}
}
protected Object initializeBean(String beanName,Object bean,BeanDefinition beanDefinition){
//执行BeanPostProcessor的前置处理
Object wrappedBean = applyBeanPostProcessorsBeforeInitialization(bean,beanName);
invokeInitMethods(beanName,wrappedBean,beanDefinition);
//执行BeanPostProcessor的后置处理
wrappedBean = applyBeanPostProcessorsAfterInitialization(bean,beanName);
return wrappedBean;
}
@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean,String beanName) throws BeansException{
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
/**
* 执行bean的初始化方法
*
* @param beanName
* @param bean
* @param beanDefinition
* @throws Throwable
*/
protected void invokeInitMethods(String beanName, Object bean, BeanDefinition beanDefinition) {
//TODO 后面会实现
System.out.println("执行bean[" + beanName + "]的初始化方法");
}
/**
* 获取实例化对象
* @return
*/
public InstantiationStrategy getInstantiationStrategy(){
return instantiationStrategy;
}
public void setInstantiationStrategy(InstantiationStrategy instantiationStrategy){
this.instantiationStrategy = instantiationStrategy;
}
}
- 编写BeanPostProcessor的具体实现类,重写postProcessBeforeInitialization和postProcessAfterInitialization方法,可以根据自己的定义重写其中的内容,然后在上一步中执行,这样关于这一块就走通了。
public class CustomerBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("CustomerBeanPostProcessor#postProcessBeforeInitialization");
//换兰博基尼
if ("car".equals(beanName)) {
((Car) bean).setBrand("lamborghini");
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("CustomerBeanPostProcessor#postProcessAfterInitialization");
return bean;
}
}
- 测试
@Test
public void testBeanPostProcessor() throws Exception {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
beanDefinitionReader.loadBeanDefinition("classpath:spring.xml");
//添加bean实例化后的处理器
CustomerBeanPostProcessor customerBeanPostProcessor = new CustomerBeanPostProcessor();
beanFactory.addBeanPostProcessor(customerBeanPostProcessor);
Car car = (Car) beanFactory.getBean("car");
System.out.println(car);
//brand属性在CustomerBeanPostProcessor中被修改为lamborghini
}
- 总结
BeanFactoryPostProcessor和BeanPostProcessor提供了给BeanDefinition和Bean做横向扩展的能力,为实现AOP打下了坚实的基础!