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对象,并缓存到容器中

  • 相关阅读:
    LeetCode "Palindrome Partition II"
    LeetCode "Longest Substring Without Repeating Characters"
    LeetCode "Wildcard Matching"
    LeetCode "Best Time to Buy and Sell Stock II"
    LeetCodeEPI "Best Time to Buy and Sell Stock"
    LeetCode "Substring with Concatenation of All Words"
    LeetCode "Word Break II"
    LeetCode "Word Break"
    Some thoughts..
    LeetCode "Longest Valid Parentheses"
  • 原文地址:https://www.cnblogs.com/doagain/p/15635680.html
Copyright © 2011-2022 走看看