##概述
Spring作为Java项目中使用最广泛的框架,它的扩展性毋庸置疑,核心的容器功能从13年前的第一版到现在没变动过,只是在原先基础中不断添加新的能力,那新的功能是如何添加,这要说到Spring留给框架自身和使用者的两个接口BeanPostProcessor和BeanFactoryPostProcessor (另外FactoryBean也是很重要的扩展接口)
##Bean初始化回调接口- BeanPostProcessor BeanPostProessor是Spring工厂的一个“钩子”接口,允许Bean实例化前后对Bean进行修改和增强 BeanPostProcessor接口定义如下:
//Bean实例的初始化回调接口 包括初始化前后初始化后 类似InitializingBean
//接口的afterPropertiesSet方法
// bean:Bean对象,beanName:Bean定义名称
public interface BeanPostProcessor{
//Bean实例初始化之前调用
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
//Bean实例初始化之后调用
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}
Spring框架很多功能通过继承BeanPostProcessor接口的来实现:
比如
- AutowiredAnnotationBeanPostProcessor实现@Autowired注解实现属性自动注入
- BeanValidationPostProcessor实现JavaBean属性校验(当然具体校验实现是JSR-303校验框架来做)
- 很多Spring AOP功能实现,比如BeanNameAutoProxyCreator
ApplicationContext会自动检测实现BeanPostProcessor类,并应用在Bean初始化上,而BeanFactory
Bean工厂初始化后修改Bean配置接口-BeanFactoryPostProcessor
除了BeanPostProcessor另外一大扩展接口就是BeanFactoryPostProcessor BeanFactoryPostProcessor可以修改ApplicationContext中的bean definitions,实现Bean功能近一步扩展
- 属性占位符配置 (context:property-placeholder PropertySourcesPlaceholderConfigurer)
- bean的自动扫描配置(context:component-scan ConfigurationClassPostProcessor)
- 属性类型转换处理(CustomEditorConfigurer)
BeanFactoryPostProcessor接口定义
public interface BeanFactoryPostProcessor{
//beanFactory初始化完成后修改ApplicationContext的内部BeanFactory
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
例子 比如我们项目中所有实体类继承BaseModel,Model创建时候统一进行一些公共属性(createTime,updateTime)初始化
@Service
public class BaseModelBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("BaseModelBeanFactoryPostProcessor.postProcessBeanFactory");
String[] beanDefinitionNames = beanFactory.getBeanDefinitionNames();
for (String def : beanDefinitionNames) {
BeanDefinition beanDefinition = beanFactory.getBeanDefinition(def);
MutablePropertyValues mpv = beanDefinition.getPropertyValues();
if (beanDefinition.getBeanClassName().endsWith("Model")) {
beanDefinition.getPropertyValues().add("createTime", new Timestamp(System.currentTimeMillis()));
beanDefinition.getPropertyValues().add("updateTime", new Timestamp(System.currentTimeMillis()));
}
}
}
}