Spring经过XML解析获取到了所有需要实例化Bean的信息并读取到BeanDefinition后,就保存在了BeanDefinitionMap容器中。在实例化bean的操作就是依据这些BeanDefinition定义来做,而在实例化之前,Spring允许我们通过自定义扩展来改变bean的定义。定义一旦变了,后面的实例也就变了。而beanFactory后置处理器,既BeanFactoryPostProcessor就是用来改变bean定义的。
invokeBeanFactoryPostProcessors(beanFactory)
// 创建BeanFactory,并且把定义的Bean的信息读取到了BeanDefinition中
invokeBeanFactoryPostProcessors(beanFactory);
// BeanDefinitionRegistryPostProcessor 和 BeanFactoryPostProcessor接口的调用
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
在加载完BeanDefinition后紧接着就会执行obtainFreshBeanFactory,帮我们调用实现了BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor接口的方法。
BeanDefinitionRegistryPostProcessor继承了BeanFactoryPostProcessor接口,所以它们一共有两个核心的方法:
@Component
public class WintigBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
/**
* 在实例化之前,可以对BeanDefinition进行修改和注册
* @param registry the bean definition registry used by the application context
* @throws BeansException
*/
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
// 获取所有beanDefinitionNames
String[] beanDefinitionNames = registry.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
// 根据name获取beanDefinition
BeanDefinition beanDefinition = registry.getBeanDefinition(beanDefinitionName);
}
// 新增beanDefinition
GenericBeanDefinition genericBeanDefinition = new GenericBeanDefinition();
genericBeanDefinition.setBeanClass(GenericBeanDefinitionBean.class);
// 属性设置
MutablePropertyValues propertyValues = genericBeanDefinition.getPropertyValues();
propertyValues.add("name", "wintig");
registry.registerBeanDefinition("genericBeanDefinitionBean", genericBeanDefinition);
// 删除指定beanDefinition
registry.removeBeanDefinition("genericBeanDefinitionBean");
// 自定义扫描器
// 就完成了"com.wintig"路径下,有WintigService注解类的扫描
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(registry);
scanner.addIncludeFilter(new AnnotationTypeFilter(WintigService.class));
scanner.scan("com.wintig");
}
/**
* 拿到beanFactory容器,你可以根据业务进行扩展
* @param beanFactory the bean factory used by the application context
* @throws BeansException
*/
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
DefaultListableBeanFactory listableBeanFactory = (DefaultListableBeanFactory)beanFactory;
// 允许使用相同名称重新注册不同的bean实现
listableBeanFactory.setAllowBeanDefinitionOverriding(true);
// 允许循环依赖
listableBeanFactory.setAllowCircularReferences(true);
}
public class GenericBeanDefinitionBean {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}