(造轮子)手写Spring框架-BeanFactoryPostProcessor和BeanPostProcessor

99 阅读5分钟

BeanFactoryPostProcessor和BeanPostProcessor

代码地址:github.com/WangChao-ly…

建议订阅博主专栏,从下到上系统手写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

  1. 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;
}
  1. 编写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"));
    }
}
  1. 测试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

  1. 该接口提供了两个方法,一个在初始化之前执行,一个在初始化之后执行,这里是实现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;
}
  1. 在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;
}
  1. 在ConfigurableBeanFactory中加入方法addBeanPostProcessor,该方法用来将BeanPostProcessor加入到容器中的list中,后续需要获取这些BeanPostProcessor。
public interface ConfigurableBeanFactory extends HierarchicalBeanFactory,SingletonBeanRegistry {
    /**
     * 添加BeanPostProcessor
     * @param beanPostProcessor
     */
    void addBeanPostProcessor(BeanPostProcessor beanPostProcessor);
}
  1. 在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;
}
  1. 在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;
    }
}
  1. 编写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;
    }
}
  1. 测试
@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打下了坚实的基础!