您现在的位置是:首页 >学无止境 >[源码系列:手写spring] IOC第八节:BeanFactoryPostProcessor和BeanPostProcessor网站首页学无止境

[源码系列:手写spring] IOC第八节:BeanFactoryPostProcessor和BeanPostProcessor

一辉ComeOn 2023-06-05 08:00:02
简介[源码系列:手写spring] IOC第八节:BeanFactoryPostProcessor和BeanPostProcessor

内容介绍

BeanFactoryPostProcessor和BeanPostProcessor是spring中具有重量级地位的两个接口,理解了这两个接口的主要作用,基本就理解Spring的核心原理了。为了便于理解将分成两篇文章介绍。

BeanFactoryPostProcessor

BeanFactoryPostProcessor是spring容器的后置处理器,是spring提供的容器扩展机制,它的调用时机是在spring容器实例化任何一个bean之前,也就是说在容器完成BeanDefinition读取之后,bean实例化之前。这个后置处理器可以操作容器中的bean定义信息,可以修改属性值,也可以添加新的bean定义信息。重要的实现类有以下两个:

  • PropertyPlaceholderConfigurer:用properties文件的配置值替换xml文件中的占位符
  • CustomEditorConfigurer:实现类型转换。

BeanFactoryPostProcessor的实现比较简单,大家可以根据下面的单元测试debug一下。

BeanPostProcessor

BeanPostProcessor也是spring提供的容器扩展机制,而它的调用时机是在每一个bean实例化之后,在初始化方法调用之前和之后。BeanPostProcessor可以对bean的属性进行更改,它也可以返回一个完全不同的实例来替换掉原来的bean,也是后面实现AOP的关键。

BeanPostProcessor的两个方法分别在bean执行初始化方法(后面实现)之前和之后执行。

public interface BeanPostProcessor {
	/**
	 * 在bean执行初始化方法之前执行此方法
	 */
	Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;

	/**
	 * 在bean执行初始化方法之后执行此方法
	 */
	Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}

 

代码仓库

完整代码

bean-factory-post-processor-and-bean-post-processorhttps://github.com/yihuiaa/little-spring/tree/bean-factory-post-processor-and-bean-post-processor


核心代码

BeanFactoryPostProcessor接口

定义bean处置方法,允许自定义修改BeanDefinition的属性值。

/**
 * ● @author: YiHui
 * ● @date: Created in 21:37  2023/4/17
 * ● @notes: 允许自定义修改BeanDefinition的属性值
 */
public interface BeanFactoryPostProcessor {
    /**
     * BeanDefinition加载完成后,bean实例化之前,提供修改BeanDefinition属性值的机制
     * @param beanFactory
     * @throws BeansException
     */
    void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}

BeanPostProcessor接口

定义bean处置方法,用于修改实例化后的bean的修改扩展点。

/**
 * ● @author: YiHui
 * ● @date: Created in 22:21  2023/4/17
 * ● @notes: 用于修改实例化后的bean的修改扩展点
 */
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;
}

AutowireCapableBeanFactory

定义BeanFactory的自动装载方法

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;
}

AbstractBeanFactory

添加beanPostProcessors列表属性

/**
 * ● @author: YiHui
 * ● @date: Created in 16:20  2023/2/20
 * ● @notes:抽象bean工厂,提供获取bean的模版方法
 */
public abstract class AbstractBeanFactory extends DefaultSingletonBeanRegistry implements ConfigurableBeanFactory {

    private final List<BeanPostProcessor> beanPostProcessors = new ArrayList<>();
   

    public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor){
        //有则覆盖
        beanPostProcessors.remove(beanPostProcessor);
        beanPostProcessors.add(beanPostProcessor);
    }

    public List<BeanPostProcessor> getBeanPostProcessors() {
        return beanPostProcessors;
    }

省略其他代码...

AbstractAutowireCapableBeanFactory

createBean方法修改,bean实例化时新增bean初始化方法的调用。

...

@Override
 protected Object createBean(String name, BeanDefinition beanDefinition,Object[] args) {
        Object bean = null;
        try {
            bean = createBeanInstance(name,beanDefinition,args);
            //填充属性
            applyPropertyValues(name,bean, beanDefinition);
            //执行bean的初始化方法和BeanPostProcessor的前置和后置处理方法
            initializeBean(name, bean, beanDefinition);
        }catch(Exception e){
            throw new BeansException("Fail to instantiation",e);
        }
        addSingleton(name,bean);
        return bean;
    }
    
...

新增bean初始化方法 

...   

protected Object initializeBean(String beanName, Object bean,BeanDefinition beanDefinition){
        //执行BeanPostProcessor的前置处理
        Object wrappedBean = applyBeanPostProcessorsBeforeInitialization(bean, beanName);
        // todo 执行bean初始化
        invokeInitMethods(beanName,bean, beanDefinition);
        //执行BeanPostProcessor的后置处理
        wrappedBean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
        return wrappedBean;
    }
...

测试

spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
	         http://www.springframework.org/schema/beans/spring-beans.xsd
		 http://www.springframework.org/schema/context
		 http://www.springframework.org/schema/context/spring-context-4.0.xsd">

    <bean id="person" class="bean.Person">
        <property name="name" value="yiHui"/>
        <property name="car" ref="car"/>
    </bean>

    <bean id="car" class="bean.Car">
        <property name="name" value="Rolls-Royce"/>
    </bean>

</beans>

BeanFactoryPostProcessor

public class CustomBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        BeanDefinition beanDefinition = beanFactory.getBeanDefinition("person");
        PropertyValues propertyValues = beanDefinition.getPropertyValues();
        //修改name
        propertyValues.addPropertyValue(new PropertyValue("name","YiHuiComeOn"));
    }
}
    @Test
    public void BeanFactoryPostProcessor() throws Exception {
        DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
        XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(factory);
        xmlBeanDefinitionReader.loadBeanDefinitions("classpath:spring.xml");

        //BeanDefinition加载完成后,bean实例化之前,修改BeanDefinition的属性值
        CustomBeanFactoryPostProcessor beanFactoryPostProcessor = new CustomBeanFactoryPostProcessor();
        beanFactoryPostProcessor.postProcessBeanFactory(factory);

        Person person = (Person)factory.getBean("person");
        System.out.println(person);
    }

测试结果

名称在实例化之前由xml中定义的yiHui被改为YiHuiComeOn

执行bean[car]的初始化方法
执行bean[person]的初始化方法
Person{name='YiHuiComeOn', age='null', car=Car{name='Rolls-Royce'}}

BeanPostProcessor

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).setName("Maserati");
        }
        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 factory = new DefaultListableBeanFactory();
        XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(factory);
        xmlBeanDefinitionReader.loadBeanDefinitions("classpath:spring.xml");

        //添加bean实例化后的处理器
        factory.addBeanPostProcessor(new CustomerBeanPostProcessor());

        Car car = (Car)factory.getBean("car");
        System.out.println(car);

    }

测试结果

CustomerBeanPostProcessor#postProcessBeforeInitialization
执行bean[car]的初始化方法
CustomerBeanPostProcessor#postProcessAfterInitialization
Car{name='Maserati'}

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。