5. Bean配置元数据解析

2023-09-23  本文已影响0人  wyh001

解析xml配置文件、java注解类、java配置类为BeanDefinition

一、解析xml配置文件

Xml配置读取器

  1. 读取文件名称、Resource抽象,将其解析为Document

    • DocumentLoader 文档加载器
  2. 读取Document里的信息,将其解析BeanDefinition,并注册到IoC容器中

    • BeanDefinitionDocumentReader
xml解析.png
  1. 委派BeanDefinitionParserDelegate去解析xml元素和属性
    • 支持默认自定义命名空间
    • NamespaceHandlerResolver 命名空间解析器
      • DefaultNamespaceHandlerResolver 加载META-INF/spring.handlers文件中声明的命名空间处理器
    • NamespaceHandler命名空间处理器
BeanDefinitionParserDelegate.png NamespaceHandler.png

二、扫描类路径

扫描类路径,通过过滤条件筛选出候选类

TypeFilter 过滤器接口

默认注解过滤器AnnotationTypeFilter支持的注解

ConditionEvaluator 候选条件评估器

ClassPathBeanDefinitionScanner 扫描器

  1. 扫描类路径下的文件

  2. 使用索引@Indexed获取候选类

  3. 处理通用注解

    • AnnotationConfigUtils#processCommonDefinitionAnnotations(AnnotatedBeanDefinition)
    • @Lazy
    • @Primary
    • @DependsOn
  4. 注册注解配置处理器

    • AnnotationConfigUtils#registerAnnotationConfigProcessors(BeanDefinitionRegistry)
    • ConfigurationClassPostProcessor处理@Configuration
  5. ScannedGenericBeanDefinition

示例

private static void s5_1() {
    final DefaultListableBeanFactory defaultListableBeanFactory = new DefaultListableBeanFactory();
    final ClassPathBeanDefinitionScanner classPathBeanDefinitionScanner = new ClassPathBeanDefinitionScanner(defaultListableBeanFactory);

    final int count = classPathBeanDefinitionScanner.scan("org.example.service.s5");
    log.info("加载数量【{}】", count);

    final String[] beanDefinitionNames = defaultListableBeanFactory.getBeanDefinitionNames();
    log.info("[{}]", Arrays.toString(beanDefinitionNames));
}

三、解析java配置类

AnnotatedBeanDefinitionReader

四、解析@Configuration配置类

在前三种解析方式中,都可以支持解析配置类,这种方式是通过扩展IoC容器生命周期接口实现的

ConfigurationClassPostProcessor

ConfigurationClassPostProcessor.png

步骤

  1. 读取IoC容器中所有注册的BeanDefinition

  2. 筛选出配置类的BeanDefinition,通过读取元数据,将其解析为ConfigurationClass列表

    • ConfigurationClassParser
  3. 读取ConfigurationClass中的信息,构建成BeanDefinition列表,注册到IoC容器中

    ConfigurationClassBeanDefinitionReader

解析流程

解析流程.png

读取流程

读取注册.png

建议

@Configuration类中定义@Bean方法创建BeanFactoryPostProcessor时,使用static限定符,避免配置类被过早地实例化

上一篇 下一篇

猜你喜欢

热点阅读