Spring5.2.x-04-BeanDefinitionMap

ApplicationContext
AnnotationConfigAppplicationContext

AnnotationConfigApplicationContext实例化

  • 调用父类构造方法时new出来的beanFactory = new DefaultListableBeanFactory();

  • reader = new AnnotatedBeanDefinitionReader(this), 他的register方法可以把类变成BeanDefinition对象
    AnnotatedBeanDefinitionReader会调用父类AnnotatedBeanDefinitionReader实例化方法的时候, AnnotationConfigUtils.registerAnnotationConfigProcessors方法, 注册spring自带的BeanDefinition
    - org.springframework.context.annotation.internalConfigurationAnnotationProcessor(名字) ConfigurationClassPostProcessor(最重要的类)
    - org.springframework.context.annotation.internalAutowiredAnnotationProcessor AutowiredAnnotationBeanPostProcessor(解析@Autowired)
    - org.springframework.context.annotation.internalCommonAnnotationProcessor CommonAnnotationBeanPostProcessor(其中一个功能是解析@Resource)
    - org.springframework.context.event.internalEventListenerProcessor EventListenerMethodProcessor
    - org.springframework.context.event.internalEventListenerFactory DefaultEventListenerFactory

  • scanner = new ClassPathBeanDefinitionScanner(this);

BeanFactory
DefaultListableBeanFactory中的重要对象

  • beanDefinitionMap(是一个ConcurrentHashMap)

BeanDefinition中的重要对象

  • beanClass 与之对应的对象

AbstractApplicationContext#invokeBeanFactoryPostProcessors()方法

  • 获取到的BeanFactoryPostProcessor
    xml或者带注解
    通过addBeanFactoryPostProcessor进来的

Spring里谁先谁后?

  • 实现BeanFactoryPostProcessor和实现BeanDefinitionRegistryPostProcessor
  • 实现spring内置的还是实现程序员提供的BeanFactoryPostProcessor
  • 自己提供的分为注解提供的, api提供的
  • 在子类的回调方法中继续注册, 会被扫描
  • 实现PriorityOrdered接口
  • 实现Order接口

父类是不能再注册BeanDefinition

AbstractApplicationContext.refresh里面的invokeBeanFactoryPostProcessors, 做了很多事, 其中有意见就是扫描注册BeanDefinition

context.register(ContextConfig.class);和context.scan("com.test.context.bfpp");是两套扫描器, 可能会影响最初的执行过程

扫描

PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors()

  • // 防止重复执行
    Set processedBeans = new HashSet<>();

分类执行
// 父类 存储所有实现了 BeanFactoryPostProcessor 的 bean
List regularPostProcessors = new ArrayList<>();
// 子类 代表子类方法已经执行过了 存放所有实现了 BeanDefinitionRegistryPostProcessor 的 bean
List registryProcessors = new ArrayList<>();

通过api add的类, 循环list

子类: 调用其回调方法
registryProcessor.postProcessBeanDefinitionRegistry(registry)
加到子类list里
父类: 加到父类list里

接着找子类实现PriorityOrdered接口

之后根据类型查询, 到 BeanDefinitionMap 当中查找 BeanDefinitionRegistryPostProcessor(子类)的实现类, 返回名字
目前BeanDefinitionMap 只有spring内置注册的 ConfigurationClassPostProcessor
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
同时ConfigurationClassPostProcessor实现PriorityOrdered接口, 会被实例化
执行ConfigurationClassPostProcessor的子类方法

接着找子类实现Ordered接口

接着死循环直接执行子类的方法, 如果有未执行的子类, 就继续while循环

因为可以在子类的方法里手动注册未加注解的类

执行子类的父类方法

执行通过api add的实现父类的类的父类方法

准备实现priorityOrdered,order和没有实现order接口共三个list

找个各自的实现, 先执行实现priorityOrdered的父类方法, 再执行实现order的父类方法, 最后执行没有实现order接口的方法

BeanDefinitionRegistryPostProcessor 和 ImportBeanDefinitionRegistrar(只能通过@Import注入, 加@Component是没用的) 的执行顺序

先执行内置实现BeanDefinitionRegistryPostProcessor如ccpp, 在执行@Import的ImportBeanDefinitionRegistrar, 再执行通过扫描实现BeanDefinitionRegistryPostProcessor的类

BeanDefinitionRegistryPostProcessor 和 ImportBeanDefinitionRegistrar 有什么区别

ImportBeanDefinitionRegistrar 的回调参数多一个 AnnotationMetadata, 可以拿到注解里的值

Bean的注入, ImportBeanDefinitionRegistrar 或者 通过api, 反正要比 <=ccpp, 在ccpp之前或同期, 要把 beanDefinition 注册好

ignore 某些bean

posted @ 2022-08-08 22:21  RichardHaha  阅读(132)  评论(0编辑  收藏  举报