Spring 启动过程 解析配置类

博文目录

文章目录

  • 内容总结
  • refresh - invokeBeanFactoryPostProcessor
  • ConfigurationClassPostProcessor - postProcessBeanDefinitionRegistry
  • ConfigurationClassParser - parse
    • 部分工具用法说明
    • 大致流程


内容总结

refresh - invokeBeanFactoryPostProcessor

Spring 启动过程中, 在 refresh 的 invokeBeanFactoryPostProcessor 阶段, Spring 会获取到系统中所有的 BeanDefinitionRegistryPostProcessor 和 BeanFactoryPostProcessor 组件, 两者的关系与功能如下

  • BeanFactoryPostProcessor
    • postProcessBeanFactory, 可以从 BeanFactory 中获取并修改 BeanDefinition
  • BeanDefinitionRegistryPostProcessor, 是 BeanFactoryPostProcessor 的子接口, 拥有其父接口的能力
    • postProcessBeanFactory, 可以从 BeanFactory 中获取并修改 BeanDefinition
    • postProcessBeanDefinitionRegistry, 可以向 BeanFactory 中注册 BeanDefinition

Spring 在 invokeBeanFactoryPostProcessor 阶段, 会将这两种组件分组并排序, 先执行所有 BeanDefinitionRegistryPostProcessor 的 postProcessBeanDefinitionRegistry 方法, 再执行所有 BeanFactoryPostProcessor 的 postProcessBeanFactory 方法

在这些组件中, 有一个 ConfigurationClassPostProcessor, 负责配置类的扫描与解析工作, 它实现了 BeanDefinitionRegistryPostProcessor 接口, 即同时实现了 postProcessBeanDefinitionRegistry 与 postProcessBeanFactory 两个方法, postProcessBeanDefinitionRegistry 方法内就会做配置类的解析, 扫描, 注册 BeanDefinition 等工作

ConfigurationClassPostProcessor - postProcessBeanDefinitionRegistry

大致流程

  • 首先获取到所有 BeanDefinition 的 Names, 大致有如下内容
    • new AnnotationConfigApplicationContext 时传入的配置类, 在内部被注册
    • new AnnotatedBeanDefinitionReader 时注册的一些基础架构组件
    • 因为还没有开始扫描并注册自定义 BeanDefinition, 所以这里不会包含这些
  • 遍历并获取对应的 BeanDefinition, 根据缓存判断是否是已经解析过的配置类
    • 如果该 BeanDefinition 有 configurationClass 属性, 则说明该 BeanDefinition 是一个配置类, 且已经被解析过了, 不需要再次解析
  • 如果没有解析过, 则判断该 BeanDefinition 是否符合配置类的定义, 符合配置类定义的会被添加到候选项列表中
    • 什么是配置类?
    • 有 @Configuration 注解, 且注解的 proxyBeanMethods 属性的值为 true, 则该类是配置类, 且是 FULL 类型的
    • 有 @Configuration 注解, 但注解的 proxyBeanMethods 属性的值为 false, 则该类是配置类, 但是是 LITE 类型的
    • 没有 @Configuration 注解, 且类不是接口, 且满足下面两个条件中的任意一个, 同样是配置类, 是 LITE 类型的
      • 类上有 @Component, @ComponentScan, @Import, @ImportResource 中的任意一个
      • 类里有 @Bean 注解标注的方法
  • 如果候选列表是空的, 说明没有找到配置类, 该方法终止
  • 如果有找到候选项, 排序, 实例化 BeanNameGenerator 和 Environment
  • 实例化一个配置类解析器 ConfigurationClassParser
  • 使用配置类解析器来解析配置类, 如果解析的过程中发现了新的其他配置类, 则递归解析之

ConfigurationClassParser - parse

配置类解析器, 用来解析配置类

部分工具用法说明

  • @Component, 如果一个类上有该注解及其其衍生注解, 如 @Controller, @Service, @Repository 等, 则 Spring 扫描过程中, 该类会被扫描成为 BeanDefinition, 最终被创建为 Bean
  • @ComponentScan, Spring 会扫描通过该注解指定的包及其子包, 并查找带有@Component 注解及其其衍生注解, 如 @Controller, @Service, @Repository 等的类, 将其注册成为 BeanDefinition, 最终被创建为 Bean
  • @ComponentScans, 里面可以放多个 @ComponentScan, 每一个子项都将依次被扫描
  • @Import, 通过该注解将类引入 Spring, 和 @Bean 有部分功能重叠
    • 如果被引入的类是 ImportSelector, 该接口定义了 selectImports 方法, 返回的是一组全限定类名数组, 这些类最终被注册成为 BeanDefinition, 而实现 ImportSelector 的类则不会被注册成为 BeanDefinition
      • 如果被引入的类是 DeferredImportSelector, 延迟导入, ImportSelector 在解析配置类的时候就顺带处理掉了, 而 DeferredImportSelector 在解析配置类时只是将其加入到一个容器中, 等到所有的配置类都解析完成后才会处理
    • 如果被引入的类是 ImportBeanDefinitionRegistrar, 该接口可以向 BeanFactory 注册 BeanDefinition, 定义了两个重载的 registerBeanDefinitions 方法, 一个需要指定 BeanName, 一个则使用名称生成器
    • 如果被引入的类不属于上述情况, 则该类被注册成为 BeanDefinition, BeanName 是全限定类名, 而通过 @Bean 注解的方法注册的 BeanDefinition, BeanName 是方法名
  • @ImportResource, 用于导入 XML 配置文件
  • @PropertySource, 用于让 Spring 加载特定的属性配置文件到 Environment, 通过 @Value 获取并使用之. 和 @ConfigurationProperties 组合使用, 可以将属性文件与一个类绑定, 将属性文件中的变量值注入到该类的成员变量中
  • @PropertySources, 里面可以放多个 @PropertySource

大致流程

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/657530.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Redis缓存穿透、缓存击穿、缓存雪崩的解决方案

一、背景 不管是实际工作还是面试,这3个问题都是非常常见的,今天我们就好好探讨一下这个三个问题的解决方案 三者的区别: 缓存穿透:查询缓存和数据库都不存在的数据,缓存没有,数据库也没有 缓存击穿&#…

【面试真题】Javascript 实现多条件过滤数组

场景: 有这么一个数组 [{a,123,b:345,c:456,d:t12},{a,234,b:345,c:thf2,d:t12}], 现在希望能够通过逗号分隔搜索值的输入方式,从数组中过滤出模糊匹配的数组元素。 解析: 可以使用 JavaScript 的 filter 函数和 indexOf 函数来实现这个功…

[经典面试题]169. 多数元素

题目描述 给定一个大小为 n 的数组 nums ,返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。 你可以假设数组是非空的,并且给定的数组总是存在多数元素。 示例 1: 输入:nums [3,2,3] 输出:3…

Java入门高频考查基础知识8(腾讯18问1.5万字参考答案)

刷题专栏:http://t.csdnimg.cn/gvB6r Java 是一种广泛使用的面向对象编程语言,在软件开发领域有着重要的地位。Java 提供了丰富的库和强大的特性,适用于多种应用场景,包括企业应用、移动应用、嵌入式系统等。 以下是几个面试技巧&…

使用AKStream对接gb28181

优点:功能比较多,C#开发的,容易修改,内嵌入了zlmk流媒体服务品,启动简单 缺点:sip对摄像头兼容还有问题,大华接入非常不稳定,注册等待时间久,对海康是正常,占…

Android 12.0 监听手机飞行模式

1. 判断当前手机飞行模式是否开启 /*** * param context* return true:飞行模式开启; false:飞行模式关闭*/ public boolean airplaneMode(Context context) {return (Settings.Global.getInt(context.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 0) 1);}2. 接…

IntelliJ Idea实用插件推荐

目录 一、插件安装 二、常用插件 A、代码规范 Alibaba Java Coding Guidelines SonarLint B、快捷开发 aiXcoder-AI代码生成 AWS Toolkit-AI代码生成 CodeGeeX-AI代码生成 CodeGlance-代码缩略图 camelCase-格式转换 GsonFormatPlus-json代码生成 Sequence Giagram…

LeetCode第606题 - 根据二叉树创建字符串

题目 解答 class Solution {public void preorder(TreeNode node, StringBuilder sb) {if (node null) {return;}sb.append(node.val);if (node.left null && node.right null) {return;}sb.append("(");preorder(node.left, sb);sb.append(")&quo…

UE4 CustomDepthMobile流程小记

原生UE opaque材质中获取CustomDepth/CustomStencil会报错 在其Compile中调用的函数中没有看到报错逻辑 材质节点的逻辑都没有什么问题,所以看一下报错 在HLSLMaterialTranslator::Translate中 修改之后 mobile流程的不透明材质可以直接获取SceneTexture::customd…

聚焦AI新动能,九州未来与燧弘华创签约!

1月24日,厦门市电子信息与人工智能产业高质量发展大会成功举办。来自电子信息产业、人工智能领域的企业家、专家等近300位嘉宾齐聚一堂,共谋智能基础,共话产业合作,共享发展商机。 会上,九州未来与燧弘华创签署算力租…

什么是XAI

可解释性AI(XAI) 可解释性AI(XAI)旨在提高人工智能系统的透明度和可理解性,使人们更好地理解AI的决策过程和原理。随着AI技术的广泛应用,XAI成为了一个备受关注的重要领域。它不仅有助于建立人们对AI的信任…

anaconda离线安装包的方法

当设备没有网络时,可以使用有网络的设备先下载所需安装包,然后离线拷贝到需要安装的设备,最后安装。 一. 下载所需安装包 下载命令:使用pip download。详细描述参见pip download -h 以"blind-watermark"为例。 pip …

​学者观察 | 区块链技术理论研究与实践观察——中央财经大学朱建明

导语 当下区块链研究成果质量越来越高,技术应用越来越成熟。在现阶段的研究中存在哪些短板需要弥补,如何将研究成果转化为推动数字经济高质量发展的实际应用,区块链技术与其他新技术结合发展将带来哪些新的机遇? 中央财经大学朱…

eduSRC那些事儿-3(命令执行类+越权逻辑类)

点击星标,即时接收最新推文 本文对edusrc挖掘的部分漏洞进行整理,将案例脱敏后输出成文章,不包含0DAY/BYPASS的案例过程,仅对挖掘思路和方法进行相关讲解。 命令执行类 St2命令执行 在电量查询手机管理平台,观察到.do或…

大坑!react+thress.js

2. UI交互界面与Canvas画布叠加 | Three.js中文网 (webgl3d.cn) // canvas画布绝对定位 renderer.domElement.style.position absolute; renderer.domElement.style.top 0px; renderer.domElement.style.left 0px; renderer.domElement.style.zIndex -1; 我按照教程设置了…

不看后悔之JavaEE Web开发预备知识篇:HTML5、CSS3与JavaScript前端三剑客——搭建企业级应用的基石

引言 在JavaEE企业级Web开发中,HTML5、CSS3和JavaScript作为前端技术的核心力量,为构建高性能、高交互的企业应用程序提供了不可或缺的基础支撑。本文将详尽探讨这三种技术在JavaEE环境下的基本概念、核心功能以及最佳实践,助你顺利开启Java…

Golang的数字签名之旅:crypto/ecdsa库详解

Golang的数字签名之旅:crypto/ecdsa库详解 引言crypto/ecdsa库概览基本功能安装和设置使用场景 ECDSA原理简介椭圆曲线密码学基础ECDSA的工作原理安全性考虑 Golang中ECDSA的实现密钥生成数字签名签名验证 crypto/ecdsa的高级应用性能优化安全性考虑实际应用案例 总…

Python列表中的extend功能及用法举例

Python列表中的extend功能及用法举例 🌵文章目录🌵 🌳引言🌳🌳extend()🌳🍀功能介绍🍀🍀语法🍀🍀示例🍀🍀注意事项&#x…

掌握 Android JNI 基础

写在前面 最近在看一些底层源码,发现 JNI 这块还是有必要系统的看一下,索性就写一写博客,加深加深印象🍻 本文重点聊一聊一些干货,避免长篇大论 JNI 概述 JNI 是什么? 定义:Java Native In…

用GPT写PHP框架

参考https://www.askchat.ai?r237422 写一个mvc框架 上面是简单的案例,完整的PHP框架,其核心通常包含以下几个关键组件: 1. 路由(Routing):路由组件负责解析请求的URL,并将其映射到相应的控制…