SpringBoot系列

6) 再理解BeanPostProcessor以及BeanFac

2021-03-06  本文已影响0人  涣涣虚心0215

在Spring开发过程中使用的最多的注解就是@Autowired以及@Value,来为bean的依赖赋值,那么这写Annotation是如何实现的呢?Spring IOC主要工作其实就是创建Bean的实例并初始化bean,当bean中存在这些注解,那么可以通过BeanPostProcessor来对bean的实例进行修改。

BeanPostProcessor

从BeanPostProcessor的Javadoc文档就能看出它的主要作用,而它所提供的两个方法应用在不同的两个场景。

//Typically, post-processors that populate beans via marker interfaces or the like 
//will implement postProcessBeforeInitialization, 
//while post-processors that wrap beans with proxies 
//will normally implement postProcessAfterInitialization.
public interface BeanPostProcessor {
    default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
    default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
}
BeanFactoryPostProcessor

BeanFactoryPostProcessor会被自动检测到,然后在开始创建bean之前(所以这个时候BeanFactory是没有任何bean实例被创建),应用postProcessBeanFactory这个方法,可以更改BeanFactory中任意BeanDefinition。
常用的类是PropertyResourceConfigurer的子类(PropertyPlaceholderConfigurer处理bean定义中"${name}"这样的占位符解析),可以通过读取外部Configure的property更新BeanFactory中的BeanDefinition。

public interface BeanFactoryPostProcessor {
    void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
BeanDefinitionRegistryPostProcessor

BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子类,更是针对BeanDefinition来做的,从BeanDefinitionRegistry中来获得BeanDefinition,然后更新BeanDefinition的值。
而BeanFactoryPostProcessor提供的方法参数是BeanFactory,所以它的额外作用可以创建新的BeanDefinition到BeanFactory中。

public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
    void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;

}

看看二者使用的区别

public class BeanDefinitionPostProcessor implements BeanDefinitionRegistryPostProcessor {
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        //只能对BeanFactory中的BeanDefinition做更新
        BeanDefinition student = registry.getBeanDefinition("student");
        student.getPropertyValues().getPropertyValue("name").setConvertedValue("Test");
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        //可以对BeanFactory中BeanDefinition做更多操作,哪怕register成新的BeanDefinition
        BeanDefinition student = beanFactory.getBeanDefinition("student");
        student.getPropertyValues().getPropertyValue("name").setConvertedValue("Test1");
        ((DefaultListableBeanFactory) beanFactory).registerBeanDefinition("test" ,student);
    }
}
上一篇 下一篇

猜你喜欢

热点阅读