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()
- // 防止重复执行
SetprocessedBeans = new HashSet<>();
分类执行
// 父类 存储所有实现了 BeanFactoryPostProcessor 的 bean
List
// 子类 代表子类方法已经执行过了 存放所有实现了 BeanDefinitionRegistryPostProcessor 的 bean
List
通过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 注册好