您现在的位置是:首页 >学无止境 >[源码系列:手写spring] IOC第八节:BeanFactoryPostProcessor和BeanPostProcessor网站首页学无止境
[源码系列:手写spring] IOC第八节:BeanFactoryPostProcessor和BeanPostProcessor
简介[源码系列:手写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;
}
代码仓库
完整代码
核心代码
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'}
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。