在Spring开发过程中使用的最多的注解就是@Autowired以及@Value,来为bean的依赖赋值,那么这写Annotation是如何实现的呢?Spring IOC主要工作其实就是创建Bean的实例并初始化bean,当bean中存在这些注解,那么可以通过BeanPostProcessor来对bean的实例进行修改。
BeanPostProcessor
从BeanPostProcessor的Javadoc文档就能看出它的主要作用,而它所提供的两个方法应用在不同的两个场景。
- postProcessBeforeInitialization:在afterPropertiesSet 或者custom init-method被调用之前,对bean进行修改。
- postProcessAfterInitialization:在afterPropertiesSet 或者custom init-method被调用之后,对bean进行修改,更多是包装代理对象。
常见类就是AutowiredAnnotationBeanPostProcessor。
//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);
}
}
网友评论