BeanDefinitionRegistryPostProcessor详解
程序员文章站
2022-07-03 19:08:42
接口该接口继承了BeanFactoryPostProcessor接口,此接口中只有一个方法,就是postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)代码public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {/** * Modify the application context's intern...
参考
- spring源码阅读环境准备
- ConfigurationClassPostProcessor 注册
- BeanFactoryPostProcessor 接口调用源码分析
- BeanDefinitionRegistryPostProcessor详解
接口
该接口继承了BeanFactoryPostProcessor接口,此接口中只有一个方法,就是postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)
代码
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
/**
* Modify the application context's internal bean definition registry after its
* standard initialization. All regular bean definitions will have been loaded,
* but no beans will have been instantiated yet. This allows for adding further
* bean definitions before the next post-processing phase kicks in.
* @param registry the bean definition registry used by the application context
* @throws org.springframework.beans.BeansException in case of errors
*/
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
}
方法简介
也就是说,该接口主要是对BeanDefintion的增删查改
调用demo
- 类student
public class Student
{
private String name = "zhangsan";
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
'}';
}
}
- 手写一个接口,这个接口实现BeanDefinitionRegistryPostProcessor和接口PriorityOrdered,在postProcessBeanDefinitionRegistry方法中对bean的操作进行增删查改
@Component
public class BeanDefinitionRegistryPostProcessorTest implements BeanDefinitionRegistryPostProcessor, PriorityOrdered
{
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException
{
// 新增
BeanDefinition bd = new GenericBeanDefinition();
bd.setBeanClassName("com.jiumozhi.spring.annotation.Student");
registry.registerBeanDefinition("student",bd);
// 查询和修改
BeanDefinition student = registry.getBeanDefinition("student");
// 删除
registry.removeBeanDefinition("student");
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException
{
System.out.println("============= BeanDefinitionRegistryPostProcessorTest invoke beanFactory =========");
}
@Override
public int getOrder()
{
return 1;
}
}
- 启动类
@ComponentScan(basePackages = "com.jiumozhi.spring.annotation")
public class AnnotationTest {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AnnotationTest.class);
// User user = context.getBean(User.class);
// System.out.println("==========="+user);
//
// BdTest test = context.getBean(BdTest.class);
// System.out.println("==========="+test.getUrl());
Student bean = context.getBean(Student.class);
System.out.println("================"+bean.getName()+"===================");
}
}
- 上述代码会抛出空指针异常,因为我们把Student的bd删除了
调用时序及源码分析
调用时序
也就是说,该接口的调用时序是非常靠前的,基本上容器初始化的一些操作就是为了调用这个接口而做准备的。有一个特别关键的实现类,就是ConfigurationClassPostProcessor 类,在这里它作为一个普通的实现类去执行,但也是关键的创建bd的代码。
源码分析
- org.springframework.context.support.AbstractApplicationContext#invokeBeanFactoryPostProcessors
具体执行流程
- 调用实现了PriorityOrdered接口的实现(这里会调用ConfigurationClassPostProcessor 的对应实现方法)
- 调用视线了Ordered接口的
- 调用其他的
问题研究
发现我自己实现了PriorityOrdered接口的类,在第二步进行了调用。
查看源码
这个接口也继承了Ordered接口,所以在第二步调用的包括了两个
- 第一步漏掉的PriorityOrdered
- 单纯实现了Ordered接口的
本文地址:https://blog.csdn.net/qq_22986265/article/details/112791601