Spring Boot:让你轻松掌握自动装配的奥秘

2023-11-08

Spring Boot是基于Spring框架开发的一种应用框架,它通过自动装配机制,大大简化了Spring应用的开发和部署,使开发者可以更加专注于业务逻辑的实现,而无需过多关注Bean的实例化和装配过程。本文将从以下几个方面介绍Spring Boot的自动装配原理:

- 什么是自动装配
- 自动装配的核心注解
- 自动装配的实现流程
- 自动装配的条件判断
- 自动装配的优缺点

目录

一、什么是自动装配

二、自动装配的核心注解

三、自动装配的实现流程

四、自动装配的条件判断

五、自动装配的优缺点


一、什么是自动装配

自动装配是指Spring Boot根据项目中引入的依赖,自动配置相关的Bean,并将它们注册到Spring容器中,从而实现某些功能或特性。例如,如果我们在项目中引入了spring-boot-starter-web依赖,那么Spring Boot就会自动配置一个嵌入式的Tomcat服务器,一个DispatcherServlet,以及一些其他与Web开发相关的Bean。

自动装配可以简单理解为:通过注解或者一些简单的配置就能在Spring Boot的帮助下实现某块功能。

二、自动装配的核心注解

要启用Spring Boot的自动装配功能,我们需要在主程序类上添加一个核心注解:@SpringBootApplication。这个注解是一个组合注解,由以下三个注解组成:

- @SpringBootConfiguration:标注在某个类上,表示这是一个Spring Boot的配置类;
- @EnableAutoConfiguration:开启自动装配功能;
- @ComponentScan:配置扫描路径,用于加载使用注解格式定义的Bean。

其中@EnableAutoConfiguration注解又由以下两个注解组成:

- @AutoConfigurationPackage:指定了默认的包规则,就是将主程序类所在包及所有子包下的组件扫描到Spring容器中;
- @Import(AutoConfigurationImportSelector.class):通过@Import注解导入AutoConfigurationImportSelector类,然后通过该类的selectImports方法去读取META-INF/spring.factories文件中配置的组件,并按照一定的规则过滤和加载它们。

三、自动装配的实现流程

为了更清楚地理解自动装配的原理和过程,我们可以通过以下几个步骤来分析:

1. 当我们运行主程序类时,首先会创建一个SpringApplication对象,并调用其run方法来启动应用;
2. SpringApplication对象会创建一个DefaultApplicationContext对象作为应用上下文,并调用其refresh方法来初始化容器;
3. 在refresh方法中,会调用invokeBeanFactoryPostProcessors方法来执行BeanFactory后置处理器;
4. 在invokeBeanFactoryPostProcessors方法中,会调用getBeanFactoryPostProcessors方法来获取所有已注册的后置处理器,并将它们分为两类:实现了PriorityOrdered接口和Ordered接口的后置处理器,以及普通的后置处理器;
5. 然后会按照优先级顺序依次执行这两类后置处理器;
6. 在执行第一类后置处理器时,会遇到一个特殊的后置处理器:ConfigurationClassPostProcessor。这个后置处理器负责处理所有被@Configuration注解标记的配置类,并将它们解析成Bean定义注册到容器中;
7. 在执行ConfigurationClassPostProcessor时,会调用processConfigBeanDefinitions方法来处理配置类;
8. 在processConfigBeanDefinitions方法中,会创建一个ConfigurationClassParser对象来解析配置类,并调用其parse方法;
9. 在parse方法中,会遍历所有的配置类,并调用processConfigurationClass方法来处理每个配置类;
10. 在processConfigurationClass方法中,会检查配置类上是否有@Import注解,如果有,就会调用processImports方法来处理导入的类;
11. 在processImports方法中,会判断导入的类是否实现了ImportSelector接口或者ImportBeanDefinitionRegistrar接口,如果是,就会调用相应的方法来获取要导入的类名或者注册Bean定义;
12. 在这个过程中,会遇到一个特殊的ImportSelector实现类:AutoConfigurationImportSelector。这个类负责实现自动装配的核心逻辑;
13. AutoConfigurationImportSelector类会重写selectImports方法,该方法返回一个字符串数组,表示要导入的自动配置类的全限定名;
14. 在selectImports方法中,会调用getAutoConfigurationEntry方法来获取自动配置条目;
15. 在getAutoConfigurationEntry方法中,会调用getCandidateConfigurations方法来获取候选的自动配置类;
16. 在getCandidateConfigurations方法中,会调用SpringFactoriesLoader.loadFactoryNames方法来加载META-INF/spring.factories文件中配置的自动配置类名;
17. 然后会调用filterExclusions方法来过滤掉不符合条件的自动配置类,例如被@ConditionalOnClass等注解排除的类;
18. 最后会将剩余的自动配置类名返回给selectImports方法,并将它们作为Bean定义注册到容器中。

 

四、自动装配的条件判断

在自动装配的过程中,有一个重要的环节是条件判断。Spring Boot提供了一系列的@Conditional注解,用于根据不同的条件来决定是否加载某个自动配置类。这些注解包括:

- @ConditionalOnBean:当容器中存在指定Bean时,才加载该自动配置类;
- @ConditionalOnMissingBean:当容器中不存在指定Bean时,才加载该自动配置类;
- @ConditionalOnClass:当类路径中存在指定类时,才加载该自动配置类;
- @ConditionalOnMissingClass:当类路径中不存在指定类时,才加载该自动配置类;
- @ConditionalOnProperty:当配置文件中存在指定属性时,才加载该自动配置类;
- @ConditionalOnResource:当资源文件中存在指定内容时,才加载该自动配置类;
- @ConditionalOnWebApplication:当应用是一个Web应用时,才加载该自动配置类;
- @ConditionalOnNotWebApplication:当应用不是一个Web应用时,才加载该自动配置类;
- @ConditionalOnExpression:当满足SpEL表达式时,才加载该自动配置类;

这些注解可以组合使用,也可以自定义条件注解。Spring Boot会在加载自动配置类之前,检查这些注解的条件是否成立,如果不成立,则跳过该自动配置类。

五、自动装配的优缺点

Spring Boot的自动装配机制带来了很多好处,例如:

- 简化了Spring应用的开发和部署,无需编写繁琐的XML或Java配置文件;
- 提高了开发效率和质量,减少了出错和调试的可能性;
- 增强了可扩展性和灵活性,可以根据不同的场景和需求选择不同的starter和属性进行定制化;

但是,自动装配机制也有一些缺点和风险,例如:

- 增加了项目的依赖和复杂度,可能导致版本冲突或者不兼容的问题;
- 降低了项目的可控性和透明度,可能导致一些隐蔽或者意外的问题;
- 降低了项目的性能和资源利用率,可能导致一些冗余或者无用的Bean被加载到容器中;

因此,在使用Spring Boot的自动装配功能时,我们需要有一定的判断和选择,不能盲目地依赖和信任它。我们需要了解自动装配的原理和过程,以及如何通过配置文件或者代码来调整和覆盖它。我们也需要注意自动装配可能带来的问题和风险,以及如何通过测试和监控来发现和解决它们。

总之,Spring Boot的自动装配是一个强大而方便的特性,但也是一个需要谨慎而理性的特性。只有在充分理解和掌握它的基础上,才能更好地利用它,而不是被它所限制或者误导。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spring Boot:让你轻松掌握自动装配的奥秘 的相关文章

  • 安卓。 onEditorAction 从未被调用

    我正在尝试捕捉从屏幕上移除键盘的事件 并且我正在使用OnEditorActionListener班级 然而 其onEditorAction方法永远不会被调用 这是我的 XML 格式的 EditText
  • 从 PDF 中提取不可选择的内容

    我正在使用 Apache PDFBox 从 PDF 文件中提取页面 但找不到提取不可选择的内容 文本或图像 的方法 从 PDF 文件中选择内容是没有问题的 请注意 相关 PDF 在复制内容方面没有任何限制 至少从我在文件的 文档限制摘要 中
  • 将比较器对象存储在数组中

    我为我的对象定义了 4 个比较器 如下所示 public static Comparator
  • Java Arraylist of object 按日期从数组列表中删除元素

    这是我的数组列表 ArrayList
  • JPA 实体中的方法是否允许抛出异常?

    我尝试创建的 Entity 有问题 当尝试使用 OpenJPA 实现在 Eclipse 中测试类时出现问题 我有not尝试过其他人 所以不确定它是否适用于他们 我的测试用例非常简单 因为它创建一个 EntityManagerFactory
  • Windows 上的虚假唤醒。是否可以?

    我最近学习了 虚假唤醒 有人说这个问题只可能发生在某些类型的 Linux PC 上 我用的是窗户 我为虚假唤醒编写了测试 我得到的结果是这是可能的 但我想向您展示这个测试 也许我在某个地方犯了错误 我的初始变体 import java ut
  • 修复 java 内存泄漏的学习网站

    学习修复 java 内存泄漏的最佳地点是什么 我一直试图在网络上找到好的资源 但令我失望的是 我发现正在讨论玩具示例 我还能够对小型玩具转储进行故障排除 但现实世界的应用程序转储更具挑战性 并且提供的线索很少 我尝试过 Jhat JMap
  • 如何从 .t​​xt 文件读取数据并将数据放入对象的数组列表中?

    到目前为止 我所写的内容是基于我目前对基本数组的了解 但我只是不明白如何使用数组列表 或如何从文件中读取 到目前为止我所写的内容有效 任何有助于修复我的代码以从文件中读取并使用数组列表的链接或建议将不胜感激 谢谢 public class
  • java中如何围绕另一个移动对象旋转一个对象?

    我对 Java 很陌生 想要编写一个简单的太阳系统 其中月球绕地球旋转 地球绕太阳旋转 一切正常 除了月亮不想正确移动 由于地球偏离月球的初始位置 月球的自转半径会根据该距离而增大 同样 当地球接近月球惯性位置时 自转半径会减小 如果初始位
  • 如何通过keytool命令删除已经导入的证书/别名?

    我正在尝试通过 keytool 命令删除已导入的证书 keytool delete noprompt alias initcert keystore keycloak jks 但低于异常 keytool 错误 java lang Excep
  • JTable AutoCreateRowSorter 将数字排序为字符串

    我有一个 JTable JTable table new JTable String colNames c1 DefaultTableModel model new DefaultTableModel Integer x new Integ
  • Android - Java - 发送 facebook 聊天消息的意图(facebook 禁用 xmpp)

    Facebook 已弃用 xmpp API 有没有办法打开意图 或将数据传递到fb 以在Android设备上发送聊天消息 设备上安装的 Facebook 和 Messenger 应用 谢谢 您需要将 uri 传递给意图 这里10000572
  • java.sql.SQLException: - ORA-01000: 超出最大打开游标数

    我收到 ORA 01000 SQL 异常 所以我有一些与之相关的疑问 最大打开游标是否与 JDBC 连接数完全相关 或者它们也与我们为单个连接创建的语句和结果集对象相关吗 我们正在使用连接池 有没有办法配置数据库中语句 结果集对象的数量 如
  • 在 Android 中使用 lambdaj

    有人尝试过在android开发中使用lambdaj库吗 当我创建一个简单的小型java应用程序时 它对我来说工作得很好 但我无法在android应用程序中使用它 UPDATE 我正在添加 lambdaj lambdaj 2 3 2 with
  • 如何提高 Guice 启动时的性能

    好吧 我知道我的计算不客观等等 但无论如何 我讨厌在执行单元测试时等待这么多时间 我的 guice swing 应用程序需要大约 7 秒来初始化 这是一个简单的 IRC 客户端 在那一刻 没有打开连接 我什至还没有调用任何 java io
  • 在 Java 和 PHP 之间加密/解密字符串

    我使用 AES 加密来加密和解密服务器端的 php 和 Android 应用程序 作为客户端 之间的字符串 PHP 中的加密字符串为 HaxRKnMxT24kCJWUXaVvqDHahzurJQK sYA4lIHql U 在 Java 中是
  • 从 Java 调用 Python 代码时出现问题(不使用 jython)

    我发现这是从 java 运行 使用 exec 方法 python 脚本的方法之一 我在 python 文件中有一个简单的打印语句 但是 我的程序在运行时什么也没做 它既不打印Python文件中编写的语句 也不抛出异常 程序什么都不做就终止了
  • Java 中 LINQ 的等价物是什么? [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 Java 中 LINQ 的等价物是什么 没有什么比 LINQ for Java 更好的了 Edit 现在
  • 使用 Java 进行 AES 加密并使用 Javascript 进行解密

    我正在制作一个需要基于 Java 的 AES 加密和基于 JavaScript 的解密的应用程序 我使用以下代码作为基本形式进行加密 public class AESencrp private static final String ALG
  • SAXParseException:找不到元素“定义”的声明

    我对 camunda 和 DMN 完全陌生 我试图在 spring boot 中运行 DMN 示例 链接在这里 https github com camunda camunda bpm examples tree master dmn en

随机推荐

  • 【Linux】linux系统很卡排除

    1 背景 今天操作linux感觉有点卡 然后就去排查 1 1 查看内存使用情况 root localhost dataMocker free g total used free shared buff cache available Mem
  • vscode html文件自动补充html骨架失效

    vscode html文件自动补充html骨架失效 输入 Tab键补全html骨架失效 解决办法 1 让html文件处于编辑状态 按下快捷键ctrl shift p 2 在跳转的对话框里面输入change language mode 在下拉
  • 什么是动态库?什么又是静态库?(如何生成/如何使用 ! ! !)

    动态库 静态库 目录 一 gcc g 的链接方式 1 动态链接 2 静态链接 二 库的优缺点 1 动态库的优点 2 静态库的优点 三 库的生成 四 库的使用 目录 一 gcc g 的链接方式 对于我们编译一段程序经常会需要调用一个函数库 就
  • 浅谈对于servlet的见解

    众所周知 我们创建一个javaweb项目后 在客户端想要访问服务器 得发起http请求 服务器对请求会进行响应 看似简单的请求和响应有很大的门道 虽然我们都会用servlet但是不乏有人不懂其中的原理 接下来我就浅谈一下servlet的一些
  • 获取当前IP地址,跳转到对应城市网站。

    博客迁移 时空蚂蚁http cui cuihongbo com 1 代码 index php
  • COCO-stuff用法

    COCO stuff API 1 是 COCO API 2 的扩展 安装见 3 这里研究一下 COCO stuff 的用法 Files 下载链见 4 image 训练集图片 train2017 zip 验证集图片 val2017 zip 分
  • Vue+ElementUI实现将数据库中的数字展示成对应汉字

    需求 数据库中存的是数字类型 需要展示成对应的汉字 其中 1 gt 部级 2 gt 省级 3 gt 市级 4 gt 其他 dvIdxIndexList里面是从后台查到的结果集 我们首直接用map遍历后台返回的结果集 利用里面的回调对数据进行
  • 在windows10的系统下安装MySQL

    简单介绍一下 Mysql workbench的安装教程 官方网址 https www mysql com downloads 下拉到最下面 点击进去 下载这两个软件 分别是 mysql的具体网址 https dev mysql com do
  • 记一次在forEach循环中使用异步代码无效

    背景 代码如下 const res1 await getOrderPackage XM LX 95 入院检查套餐 const res2 await getOrderPackage XM LX 98 入院检验套餐 const res res1
  • 将windows10 的编码修改为UTF-8

    临时修改 只作用于当前窗口 先进入cmd命令窗口 快捷键win键 R 直接输入 chcp 65001 然后回车键 Enter键 执行 这时候本次打开的窗口编码就已经是UTF 8了 永久修改 win键 R 然后在输入框输入regedit 确定
  • mediapipe教程5:在安卓上运行mediapipe的handTracking

    一 前言和准备见mediapipe教程4 这篇博客开门见山 直接来步骤 二 在安卓上运行mediapipe的handTracking 参考网址 步骤 https google github io mediapipe getting star
  • 手游服务器微信互通,9月14日部分服务器数据互通公告

    尊敬的轩辕勇士们 轩辕传奇手游 开放测试以来人气沸腾 各种战斗的激烈程度也随之升级 为了让勇士们尽享更刺激 更热血的战斗 我们计划于9月14日6 00 9 00期间进行数据互通操作 数据互通期间 相关服务器将暂时无法进入 造成您的不便 恳请
  • 卷积神经网络的深入理解-归一化篇(Batch Normalization具体实例)

    卷积神经网络的深入理解 归一化篇 标准化 归一化 神经网络中主要用在激活之前 卷积之后 持续补充 归一化在网络中的作用 1 线性归一化 进行线性拉伸 可以增加对比度 2 零均值归一化 像素值 均值 方差 3 Batch Normalizat
  • 多路复用select、poll、epoll总结

    多路复用select poll epoll总结 一 多路复用 IO多路复用是指使用单个线程同时处理多个IO请求 在IO多路复用模型中一个线程可以监视多个文件描述符 fd 一旦某个fd就绪 读 写就绪 或者超时 就能够通知应用程序进行相应的读
  • 获取宝塔Linux面板登陆地址账号和密码

    在ssh终端输入 etc init d bt default
  • Realtime Multi-Person 2D Pose Estimation Using Part Affinity Fields

    Realtime Multi Person 2D Pose Estimation Using Part Affinity Fields 1 文章概要 文章实现了图片中的多人姿态检测 与已有的方法相比 最大的优势在于检测的速度对人物的数量不敏
  • python三方库是什么_python第三方库有哪几种

    在对于python的使用上 除了要掌握基本的操作方法外 如果有一些好用的工具辅助 效果也是非常明显的 为了能够给大家提供最大的帮助 python中的第三方库的种类也是非常多的 本篇挑选了使用功能强大 且比较好用的第三方类 整理出了它们的一些
  • R数据处理——按符号分割数据&统计两列数据组合的频数

    初始数据格式 数据格式如图所示 每个Keywords里面都含有多个关键词 使用分号 间隔开 一共有ABCDEF六个group 并且关键词有重复 最终想要的数据格式 统计所有不重复的关键词在六个group中出现的频次 使用R来处理 rm li
  • SAP CO TCODE

    CO 主数据 利润中心主数据维护 标准层次 KCH5N KCH6N 利润中心 组 非标准层次 KE51 KE52 KE53 利润中心 KCH1 KCH2 KCH3 利润中心组 成本中心主数据维护 标准层次 OKEON OKENN 成本中心
  • Spring Boot:让你轻松掌握自动装配的奥秘

    Spring Boot是基于Spring框架开发的一种应用框架 它通过自动装配机制 大大简化了Spring应用的开发和部署 使开发者可以更加专注于业务逻辑的实现 而无需过多关注Bean的实例化和装配过程 本文将从以下几个方面介绍Spring