zoukankan      html  css  js  c++  java
  • & 【04】 Spring中Xml属性配置的解析过程

    Spring容器加载方式

    1. 类路径获取配置文件(ClassPathXmlApplicationContext)
    2. 文件系统路径获取配置文件绝对路径(FileSystemXmlApplicationContext)("绝对路径")
    3. 无配置文件加载容器(AnnotationConfigApplicationContext)
    4. SpringBoot加载容器(EmbeddWebApplicationContext)

    Spring中Xml属性配置的解析过程

    gitee

    spring-framework:https://gitee.com/zb224989/spring-framework.git

    refresh()方法中的obtainFreshBeanFactory()负责把解析出来的xml标签封装成BeanDefinition对象

    BeanDefinition是Bean在实例化过程包装的对象

    image-20211128215537489

    子类实现父类的抽象方法 -> 这种行为就可以看作是模板设计模式

    image-20211128221953302

    image-20211128222041250

    1 创建XmlBeanDefinitionReader对象

    image-20211128222144148

    2 通过Reader对象加载配置文件

    image-20211128222421663

    3 把配置文件封装成Document对象

    image-20211130202727099

    4 创建BeanDefinitionDocumentReader对象,documentReader负责对document对象解析

    image-20211130202939708

    5 标签解析

    标签解析分为常规标签解析自定义标签解析

    image-20211130203310758

    5.1常规标签解析(默认标签 parseDefaultElement()方法)

    image-20211130203657363

    5.1.1 import 标签解析(importBeanDefinitionResource)

    5.1.2 Alias 标签解析 processAliasRegistration

    5.1.3 Bean 标签解析 processBeanDefinition(重点)

    image-20211130204943862

    image-20211130205054410

    1. 创建 GenericBeanDefinition 对象
    2. 解析 bean 标签的属性,并把解析出来的属性设置到 BeanDefinition 对象中
    3. 解析 bean 中的 meta 标签
    4. 解析 bean 中的 lookup-method 标签(LookupOverride)
    5. 解析 bean 中的 replaced-method 标签(ReplaceOverride)
    6. 解析 bean 中的 constructor-arg 标签
    7. 解析 bean 中的 property 标签(通过 BeanDefinition 中的 MutablePropertyValues 此类中有List<PropertyValue> propertyValueList 集合来封装<property></property> 对象)

      image-20211130205642802

    image-20211130205750856

    1. 解析bean中的qualifier标签
    2. 解析后封装成BeanDefinitionHolder,里面放置beanName和beanDefinition对象。
      beanDefinitionMap是用来放置beanDefinition对象。
      beanDefinitionNames用来放置beanName,bean实例化的时候会用到,并且有排序作用

    image-20211130210436276

    image-20211130210505741

    image-20211130210140089

    5.1.4 Beans doRegisterBeanDefinitions递归

    image-20211130210912014

    image-20211130210939904

    image-20211130211004664

    5.2 自定义标签解析(parseCustomElement()以componentScan标签为例)

    5.2.1 获取自定义标签的namespace命令空间,列如:http://www.sringframework.org/shcema/context

    5.2.2 根据命令空间获取NamespaceHandler对象(通过SPI机制获取spring中所有jar包中的META-INF/spring.handlers文件,并建立映射关系)

    image-20211202203848260

    5.2.3 反射获取NamespaceHandler实例

    5.2.4 调用对应标签如ContextNameHandler标签的init()方法

    image-20211202205102968

    eg:init()

    image-20211202215054197

    eg:component-scan 和 ComponentScanBeanDefinitionParser对象会存放到Map<String, BeanDefinitionParser> parsers = new HashMap<>()容器中

    image-20211202221021205

    每个NameHander的init()方法注册不同标签对应的不同的Parse解析器,如:ComponentScanBeanDefinitionParser

    image-20211202214939815

    5.2.5 调用handler.parse()方法完成解析

    如:CompentScan标签解析

    此时会根据属性名(eg:component-scan)从Map<String, BeanDefinitionParser> parsers = new HashMap<>()容器中获取解析对象

    image-20211202220457302

    image-20211204133616277

    5.2.5.1 获取base-package属性
    5.2.5.2 创建注解扫描器configureScanner(扫描所有.class)
    5.2.5.2.1 默认扫描过滤器扫描@Component...

    如果use-default-filters为true

    默认会扫描@Component注解、@Service注解、@Controller注解、@Repository注解。

    还会扫描@ManagedBean注解和@Named注解

    image-20211204142842661

    image-20211204144651041

    扫描器中添加需要扫描的注解类型为:Component.class,而@Service注解引用了@Comonent注解,就是@Component注解实现的功能@Service都能实现,@Service是对@Component进一步拓展。(可以理解为继承)。类似的还有@Controller注解、@Repository注解。

    image-20211204142353209

    上图注释:

    This annotation serves as a specialization of {@link Component @Component}, allowing for implementation classes to be autodetected through classpath scanning.

    这个注释充当了{@link Component @Component}的专门化,允许通过类路径扫描自动检测实现类。

    5.2.5.2.2 扫描过滤器中添加include-filter和exclude-filter

    image-20211204153342172

    5.2.5.3 scanner.doScan()->扫描装箱BeanDefinition对象

    通过层层递归扫描 base-package 下的包,先扫描出 classpath:/base-package 以.class 结尾的所有文件,然
    后再根据过滤器扫描出具有@Service 和@Component 注解的类添加到对应的集合 Set<BeanDefinition>完成
    BeanDefinition 的注册。

    image-20211204154858283

    image-20211204154611165

    image-20211204155107310

    5.2.5.3 registerComponents()中注册了几个重要的后置类

    如 :

    ConfigurationClassPostProcessor (会扫描@Configuration @Component @Bean 注解的解析)

    AutowiredAnnotationBeanPostProcessor (会扫描@Value 和@Autowired 注解)

    CommonAnnotationBeanPostProcessor (会扫描@PostConstruct 和@PreDestroy注解)

    image-20211204160320914

    image-20211204161301264

    6 BeanDefinition缓存到容器

    最终解析的标签封装成BeanDefinition对象,并缓存到容器中

  • 相关阅读:
    SQLSERVER调用DLL程序
    RAISERROR语句
    SQLSERVER表联结(INNER JOIN,LEFT JOIN,RIGHT JOIN,FULL JOIN,CROSS JOIN,CROSS APPLY,OUTER APPLY)
    SQL Server在存储过程中编写事务处理代码的三种方法
    找出表中缺失的连续数据(如:2,4,7,9;需要找出:1,3,5,6,8的数据)
    sqlserver用于统计表索引情况
    你需要了解的HTTP协议
    自己实现一个类似 jQuery 的函数库
    JS 函数 学习笔记
    JS 数组 学习笔记
  • 原文地址:https://www.cnblogs.com/doagain/p/15635680.html
Copyright © 2011-2022 走看看