【JavaEE】Spring Boot 自动装配原理(源码分析)

news2024/11/16 0:19:33

一. 前言

  • 我们在写Spring Boot的程序代码的时候, 可以注入很多我们没有定义过的Bean.
  • 例如:
    @Autowired
    private ApplicationContext applicationContext;
    @Autowired
    public DataSourceTransactionManager transactionManager;
    @Autowired
    public AutowireCapableBeanFactory autowireCapableBeanFactory;
  • 这些对象是什么时候注入进去的, Spring 是如何做的,我们可以通过阅读源码来解决这个问题.

二.Spring Boot自动装配的原理分析.

2.1 源码阅读

  • 要搞清楚自动装配的原因, 我们需要去分析Spring Boot的启动类.

  • @SpringBootApplication 标注的类 就是SpringBoot项目的启动类, 这个注解也是SpringBoot实现自动配置的核心
    在这里插入图片描述

  • 元注解:

    • JDK中提供了4个标准的用来对注解类型进行注解的注解类, 我们称之为 meta-annotation(元注
      解)
    • @Target 描述注解的使用范围(即被修饰的注解可以用在什么地方).
    • @Retention 描述注解保留的时间范围.
    • @Documented 描述在使用 javadoc 工具为类生成帮助文档时是否要保留其注解信息
    • @Inherited 使被它修饰的注解具有继承性(如果某个类使用了被@Inherited修饰的注解,则
      其子类将自动具有该注解
      )
  • @SpringBootConfiguration 在这里插入图片描述

里面就是@Configuration, 标注当前类为配置类, 其实只是做了一层封装改了个名字而已.
(@Indexed注解,是用来加速应用启动的, 不用关心), 本质上就是将启动类交给Spring进行管理

  • @ComponentScan (包扫描)
    可以通过 basePackageClasses 或 basePackages 来定义要扫描的特定包, 如果没有定义
    特定的包, 将从声明该注解的类的包开始扫描, 这也是为什么SpringBoot项目声明的注解类必须要在启动类的目录下,这样通过@Controller , @Service , @Repository , @Component , @Configuration ,@Bean标注的类/对象,就会被Spring进行管理. excludeFilters 自定义过滤器, 通常用于排除一些类, 注解等

2.2 @EnableAutoConfiguration(自动装配的核心注解)

  • 观察@EnableAutoConfiguration注解的实现:
    在这里插入图片描述
    这个注解包含两部分:

2.2.1@AutoConfigurationPackage

源码如下:
在这里插入图片描述
这个注解主要是导入一个配置文件 AutoConfigurationPackages.Registrar.class
在这里插入图片描述

  • registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry): 这个方法是ImportBeanDefinitionRegistrar接口的一部分,用于在Spring应用程序上下文中注册额外的bean定义。当一个@Configuration类使用了@Import注解并且指定了实现ImportBeanDefinitionRegistrar接口的类时,这个方法会被调用。在这个例子中,它使用PackageImports(一个假定存在的辅助类)来获取包名,并将这些包名作为字符串数组传递给另一个重载的register方法,以便在注册表中注册这些包中的类作为Spring bean定义。

  • determineImports(AnnotationMetadata metadata): 这个方法是DeterminableImports接口的一部分,用于确定哪些类应该被导入到当前的@Configuration类或@SpringBootApplication类中。在这个例子中,它返回了一个单例集合(Set),其中包含了一个PackageImports对象。这个对象封装了应该被扫描的包的信息,这样Spring就能自动发现并注册这些包中的@Component、@Service、@Repository等注解的类。

Registrar实现了 ImportBeanDefinitionRegistrar 类, 就可以被注解@Import导⼊到spring
容器里. (String[])(new PackageImports(metadata)).getPackageNames().toArray(new
String[0]) : 当前启动类所在的包名. 所以:@AutoConfigurationPackage 就是将启动类所在的包下⾯所有的组件都扫描注冊到spring 容器中.

2.2.2 @Import({AutoConfigurationImportSelector.class})

  • 使用@Import注解,导入了实现ImportSelector接口的实现类.
    在这里插入图片描述

  • selectImports() 方法底层调用 getAutoConfigurationEntry() 方法, 获取可自动配置的配置类信息集合.
    在这里插入图片描述

  • getAutoConfigurationEntry() 方法通过调用getCandidateConfigurations(annotationMetadata, attributes) 方法获取在配置文件中配置的所有自动配置类的集合
    在这里插入图片描述

  • getCandidateConfigurations 方法的功能:

    • 获取所有基METAINF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imp
      orts 文件, META-INF/spring.factories 文件中配置类的集合. 在引入的起步依赖中, 通常都有包含以上两个文件
      在这里插入图片描述

这里面包含了很多第三方依赖的配置文件(连续按两下shift可以查看对应的源码)

  1. 在加载自动配置类的时候, 并不是将所有的配置全部加载进来, 而是通过@Conditional等注解的判
    断进行动态加载.@Conditional是spring底层注解, 意思就是根据不同的条件, 来进行自己不同的条件判断,如果满足指定的条件,那么配置类里边的配置才会生效.
  2. META-INF/spring.factories文件是Spring内部提供的一个约定俗成的加载方式, 只需要在模块的
    META-INF/spring.factories文件中配置即可, Spring就会把相应的实现类注入到Spring容器中.
    注: 会加载所有jar包下的classpath路径下的META-INF/spring.factories文件, 这样文件不止一个
  • 比如 Redis的配置: RedisAutoConfiguration
    在这里插入图片描述
    由于我这个项目的pom依赖中,没有加入redis相关的依赖, 所以会根据注解@ConditionalOnMissingBean不进行加载

三.总结.

  • SpringBoot 自动配置原理的大概流程如下:
    在这里插入图片描述
    当SpringBoot程序启动时, 会加载配置文件当中所定义的配置类, 通过 @Import 注解将这些配置类全
    部加载到Spring的IOC容器中, 交给IOC容器管理

  • SpringBoot的自动配置原理源码口是 @SpringBootApplication 注解, 这个注解封装了3个注

    • @SpringBootConfiguration 标志当前类为配置类
    • @ComponentScan 进行包扫描(默认扫描的是启动类所在的当前包及其子包)
    • @EnableAutoConfiguration
      • @Import 注解 : 读取当前项目下所有依赖jar包中 META-INF/spring.factories ,
        METAINF/spring/org.springframework.boot.autoconfigure.AutoConfigurat
        ion.imports 两个文件里面定义的配置类(配置类中定义了 @Bean 注解标识的方法)
      • @AutoConfigurationPackage : 把启动类所在的包下面所有的组件都注入到 Spring
        容器中

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

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

相关文章

软件开发者消除edge浏览器下载时“此应用不安全”的拦截方法

当Microsoft Edge浏览器显示“此应用不安全”或者“已阻止此不安全的下载”这类警告时,通常是因为Windows Defender SmartScreen或者其他安全功能认为下载的文件可能存在安全风险。对于软件开发者来说,大概率是由于软件没有进行数字签名,导致…

Visual Studio 2022新建 cmake 工程测试 tensorRT 自带样例 sampleOnnxMNIST

1. 新建 cmake 工程 vs2022_cmake_sampleOnnxMNIST_test( 如何新建 cmake 工程,请参考博客:Visual Studio 2022新建 cmake 工程测试 opencv helloworld ) 2. 删除默认生成的 vs2022_cmake_sampleOnnxMNIST_test.h 头文件 3. 修改默认生成的 vs2022_cma…

【屏显MCU】多媒体接口总结

本文主要介绍【屏显MCU】的基本概念,用于开发过程中的理解 以下是图层叠加示例 【屏显MCU】多媒体接口总结 0. 个人简介 && 授权须知1. 三大引擎1.1 【显示引擎】Display Engine1.1.1 【UI】 图层的概念1.1.2 【Video】 图层的概念1.1.3 图层的 Blending 的…

一键解锁:科研服务器性能匹配秘籍,选择性能精准匹配科研任务和计算需求的服务器

一键解锁:科研服务器性能匹配秘籍 HPC科研工作站服务器集群细分领域迷途小书童 专注于HPC科研服务器细分领域kyfwq001 🎯在当今科技飞速发展的时代,科研工作对计算资源的需求日益增长😜。选择性能精准匹配科研任务和计算需求的服…

古籍双层PDF制作教程:保姆级古籍数字化教程

在智慧古籍数字化项目中,很多图书馆要求将古籍导出为双层PDF,并且确保输出双层PDF底层文本与上层图片偏移量控制在1毫米以内。那么本教程带你使用古籍数字化平台,3分钟把一个古籍书籍转化为双侧PDF。 第1步:上传古籍 点批量上传…

前序+中序、中序+后序构造二叉树

https://leetcode.cn/problems/construct-binary-tree-from-preorder-and-inorder-traversal/ https://leetcode.cn/problems/construct-binary-tree-from-inorder-and-postorder-traversal/ 前序中序 前序遍历,节点按照 [根左右] 排序。 中序遍历,节点…

JavaEE - Spring Boot 简介

1.Maven 1.1 什么是Maven 翻译过来就是: Maven是⼀个项⽬管理⼯具。基于POM(Project Object Model,项⽬对象模型)的概念,Maven可以通 过⼀⼩段描述信息来管理项⽬的构建,报告和⽂档的项⽬管理⼯具软件。 可以理解为:Maven是一个项目管理工具…

nginx隐藏server及版本号

1、背景 为了提高nginx服务器的安全性,降低被攻击的风险,需要隐藏nginx的server和版本号。 2、隐藏nginx版本号 在 http {—}里加上 server_tokens off; 如: http {……省略sendfile on;tcp_nopush on;keepalive_timeout 60;tcp_nodelay o…

ROS参数服务器增删改查实操Python

ROS参数服务器增删改查实操Python 环境准备参数服务器新增(修改)参数参数服务器获取参数参数服务器删除参数 ROS通信机制包括话题通信、服务通信和参数服务器三种通信方式,各原理及代码实现如下表 功能博客链接说明VScode配置 ROS 环境VScode…

《后端程序猿 · @Value 注释说明》

📢 大家好,我是 【战神刘玉栋】,有10多年的研发经验,致力于前后端技术栈的知识沉淀和传播。 💗 🌻 CSDN入驻不久,希望大家多多支持,后续会继续提升文章质量,绝不滥竽充数…

基于 HTML+ECharts 实现监控平台数据可视化大屏(含源码)

构建监控平台数据可视化大屏:基于 HTML 和 ECharts 的实现 监控平台的数据可视化对于实时掌握系统状态、快速响应问题至关重要。通过直观的数据展示,运维团队可以迅速发现异常,优化资源配置。本文将详细介绍如何利用 HTML 和 ECharts 实现一个…

Unity3D之TCP网络通信(客户端)

文章目录 概述TCP核心类异步机制 Unity中创建TCP客户端Unity中其它脚本获取TCP客户端接受到的数据后续改进 本文将以Unity3D应用项目作为客户端去连接制定的服务器为例进行相关说明。 Unity官网参考资料: https://developer.unity.cn/projects/6572ea1bedbc2a001ef…

go语言day17 通道channel

Golang-100-Days/Day16-20(Go语言基础进阶)/day18_channel通道.md at master rubyhan1314/Golang-100-Days (github.com) go语言day09 通道 协程的死锁-CSDN博客 channel for range 循环通道对象 单向通道 单项通道常用于函数参数,只是用来限定在函数中只能进行通道…

【Android】广播机制

【Android】广播机制 前言 广播机制是Android中一种非常重要的通信机制,用于在应用程序之间或应用程序的不同组件之间传递信息。广播可以是系统广播,也可以是自定义广播。广播机制主要包括标准广播和有序广播两种类型。 简介 在Android中&#xff0c…

【学一点儿前端】getaddrinfo ENOTFOUND registry.nlark.com“.

问题 今天jenkins打包一个项目,发现报错了 error An unexpected error occurred: "https://registry.nlark.com/xxxxxxxxxx.tgz: getaddrinfo ENOTFOUND registry.nlark.com". 先写解决方案 把yarn.lock文件里面的registry.nlark.com替换为registry.npmmi…

超低功耗ARM Cortex-M33 TZ MCU STM32WBA54、STM32WBA55:通过提升无线性能实现更出色的用户体验

摘要 STM32WBA54、STM32WBA55产品系列同时支持多种无线标准,包括Bluetooth低功耗 5.4(已认证)、Zigbee、Thread以及可用作Thread边界路由器的Matter。 该产品系列具有出色的灵活性和更强的安全性,可帮助开发人员应对不断变化的无…

二、QGroundControl开发环境搭建

文章目录 环境列表QGC源码下载编译 环境列表 QGC GithubPX4-AutopilotQt 5.15Ubuntu20.04 QGC源码下载编译 官网下载指令 如下 // Clone the repo (or your fork) including submodules: git clone --recursive -j8 https://github.com/mavlink/qgroundcontrol.git // Upda…

【vluhub】elasticsearch漏洞

Elasticsearch介绍 是Apache旗下的一个开源的、分布式、RESTful的搜索和分析引擎,适用于java语言项目 默认端口9200 kali中搭建ElasticHD, 即可未授权绕过ES可视化界面 直通车 https://github.com/360EntSecGroup-Skylar/ElasticHD/releases/download/1.4/elas…

防火墙——网络环境支持

目录 网络环境支持 防火墙的组网 web连接上防火墙 web管理口 让防火墙接到网络环境中 ​编辑 管理员用户管理 缺省管理员 接口 配置一个普通接口 创建安全区域 路由模式 透明模式 混合模式 防火墙的安全策略 防火墙转发流程 与传统包过滤的区别 创建安全策略 …

新手小白的pytorch学习第十一弹-----Computer Vision创建基础模型使用FashionMNIST

目录 PyTorch Computer Vision0 PyTorch 中 Computer vision 的库1 获得一个数据集1.1 查看数据的输入和输出形状1.2 可视化数据 2 准备 DataLoader3 Model 0: 创建一个 baseline model3.1 设置损失函数、优化器和评估指标3.2 创建一个函数来给我们的实验计时3.3 在批量数据集上…