深入理解spring 自动注入

深入理解 Spring 注入:差别、用法与原理

Spring 是 Java 开发中非常流行的框架,而依赖注入 (Dependency Injection, DI) 是其核心特性之一。本文将从以下几个方面深入探讨 Spring 注入:注入方式的差别、适用场景与用法,以及其背后的工作原理。

一、依赖注入的概念

依赖注入是一种设计模式,它通过外部配置将对象的依赖传递给对象,而不是让对象自行创建或查找依赖。Spring 框架通过 IoC (Inversion of Control) 容器实现依赖注入,从而提高了代码的可维护性和可测试性。

二、Spring 注入方式

在 Spring 中,主要有三种注入方式:

1. 构造器注入 (Constructor Injection)

构造器注入通过类的构造函数传递依赖对象。

示例代码:
@Component
public class ServiceA {
    private final DependencyB dependencyB;

    @Autowired
    public ServiceA(DependencyB dependencyB) {
        this.dependencyB = dependencyB;
    }
}
特点:
  • 强制依赖:构造器注入确保了依赖在对象创建时就完全满足。

  • 线程安全性:依赖声明为 final,确保依赖不可变。

  • 适用场景:适用于强依赖关系的场景,尤其是必需的依赖。

2. Setter 注入 (Setter Injection)

Setter 注入通过类的 setter 方法注入依赖对象。

示例代码:
@Component
public class ServiceA {
    private DependencyB dependencyB;

    @Autowired
    public void setDependencyB(DependencyB dependencyB) {
        this.dependencyB = dependencyB;
    }
}
特点:
  • 灵活性:可以选择性地注入依赖。

  • 可变性:适合需要动态更改依赖的场景。

  • 适用场景:适用于可选依赖或需要后期配置的场景。

3. 字段注入 (Field Injection)

字段注入直接通过 @Autowired 注解将依赖注入到类的字段中。

示例代码:
@Component
public class ServiceA {
    @Autowired
    private DependencyB dependencyB;
}
特点:
  • 简单易用:减少样板代码。

  • 缺乏灵活性:无法使用 final 修饰依赖,难以进行单元测试。

  • 适用场景:适用于简单场景,但不推荐在复杂项目中使用。

三、注入方式的对比

特性构造器注入Setter 注入字段注入
是否强制依赖
可测试性
灵活性
代码复杂度
推荐使用场景必需依赖可选或动态依赖简单场景

四、Spring 注入的原理

Spring 的依赖注入基于 IoC 容器,其核心是 Bean 的创建与管理。

1. IoC 容器如何创建 Bean

  1. 扫描与注册:通过 @ComponentScan 或 XML 配置扫描组件,并将其注册为 Spring 容器中的 Bean。

  2. 实例化:根据 Bean 的作用域 (Scope),通过反射创建实例。

  3. 注入依赖:根据注入方式 (构造器、Setter、字段),调用相应方法将依赖注入。

  4. 生命周期回调:执行初始化方法(如 @PostConstruct 或实现 InitializingBean 接口的 afterPropertiesSet 方法)。

2. Bean 的加载与依赖解析

Spring 容器通过以下步骤解析依赖:

  • 构造器注入:优先匹配带有参数的构造器。

  • Setter 注入:通过反射调用 setter 方法注入依赖。

  • 字段注入:通过反射直接注入字段。

3. 循环依赖的处理

Spring 提供了两种主要方式来解决循环依赖:

  • 单例模式 (Singleton):使用三级缓存机制,通过 ObjectFactory 提前暴露部分 Bean。

  • 原型模式 (Prototype):无法自动解决,需要通过设计优化避免循环依赖。

五、实际开发中的选择与注意事项

  1. 优先使用构造器注入

    • 保证依赖的完整性和不可变性。

    • 易于单元测试。

  2. Setter 注入用于可选依赖

    • 例如日志、监控组件等。

  3. 避免使用字段注入

    • 影响测试与维护,尤其在大型项目中。

  4. 保持单一职责原则

    • 尽量避免过多依赖,必要时重构代码。

六、总结

Spring 的依赖注入是简化开发、提高代码质量的重要手段。构造器注入、Setter 注入和字段注入各有优缺点,需要根据实际需求选择合适的方式。通过深入理解其原理,我们可以更高效地利用 Spring 框架构建健壮的应用程序。

希望这篇文章能帮助你更好地理解和使用 Spring 的依赖注入!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

LLVM防忘录

目录 Windows中源码编译LLVMWindows下编译LLVM Pass DLL Windows中源码编译LLVM 直接从llvm-project下载源码, 然后解压后用VS2022打开该目录, 然后利用VS的开发终端执行: cmake -S llvm -B build -G "Visual Studio 17 2022" -DLLVM_ENABLE_PROJECTSclang -DLLVM_…

adb 不是内部或外部命令,也不是可运行的程序或批处理文件。

1、问题概述? 本文讲述的是在window系统中安装了Android SDK之后,adb无法使用的情况。 在cmd中执行adb devices提示如下问题: adb 不是内部或外部命令,也不是可运行的程序或批处理文件。 问题:没有配置android sdk环…

Leetcode 第426场周赛分析总结

3370. 仅含置位位的最小整数 AC代码 class Solution { public:int smallestNumber(int n) {int x 1;while (x - 1 < n) {x << 1;}return x - 1;} };分析总结 也可以先直接获取n的长度&#xff0c;然后计算得到&#xff0c;这样时间复杂度由O(logn)优化为O(1) 在C…

【从零开始入门unity游戏开发之——unity篇05】unity6基础入门——运行游戏按钮、Game游戏窗口和Project项目窗口介绍

文章目录 运行游戏按钮、Game游戏窗口和Project项目窗口一、运行游戏按钮二、Game游戏窗口1、右上角设置1.1 如果没有相机渲染则发出警告1.2 在”编程模式”下清除每一帧1.3 窗口最大化 2、上方工具&#xff08;1&#xff09;切换手机模拟器&#xff08;2&#xff09;切换不同显…

九、Vue 事件处理器

文章目录 前言一、基础事件绑定:v-on 指令二、方法调用:组织有序的交互逻辑三、事件修饰符阻止冒泡与默认事件捕获与自身触发单次触发与鼠标按键区分四、按键修饰符前言 在 Vue.js 的交互世界里,事件处理器起着举足轻重的作用,它让页面从静态展示迈向动态交互,精准捕捉用户…

【项目】基于趋动云平台的Stable Diffusion开发

【项目】基于趋动云平台的Stable Diffusion开发 &#xff08;一&#xff09;登录趋动云&#xff08;二&#xff09;创建项目&#xff1a;&#xff08;三&#xff09;初始化开发环境&#xff1a;&#xff08;四&#xff09;运行代码&#xff08;五&#xff09;运行模型 &#xf…

VSCode下配置Blazor环境 断点调试Blazor项目

VSCode下使用Blazor的环境配置和插件推荐 Blazor是一种用于构建交互式Web UI的.NET框架&#xff0c;它可以让你使用C#、Razor和HTML进行Web开发&#xff0c;而不需要JavaScript。在这篇文章中&#xff0c;我们将介绍如何在VSCode中配置Blazor环境&#xff0c;并推荐一些有用的…

word文档中的文档网格——解决相同行间距当显示出不同行间距的情况

1 问题 被一个行间距调疯了&#xff0c;就是样式改了没用&#xff0c;格式刷刷了没用。就是肉眼可以看出行间距完全不一样。 2 解决方法 1&#xff09;修改论文正文(即出现问题文本的样式)样式&#xff1a;样式>修改>格式>段落>缩进和间距>取消"如果定义了…

ubuntu如何禁用 Snap 更新

.禁用 Snap 更新&#xff08;通过修改 snapd 配置&#xff09; 打开并编辑 /etc/apt/apt.conf.d/50unattended-upgrades文件。 这个文件控制自动更新的行为。 sudo vim /etc/apt/apt.conf.d/50unattended-upgrades 里面有一行将里面的auto改为false即可禁用更新&#xff1a;…

UniApp 原生插件开发指南

一、UniApp 原生插件开发引言 在当今的移动应用开发领域&#xff0c;跨平台开发已成为主流趋势&#xff0c;而 UniApp 作为一款强大的跨平台开发框架&#xff0c;备受开发者青睐。它凭借 “一套代码&#xff0c;多端运行” 的特性&#xff0c;极大地提高了开发效率&#xff0c…

JVM实战—9.线上FGC的几种案例

大纲 1.如何优化每秒十万QPS的社交APP的JVM性能(增加S区大小 优化内存碎片) 2.如何对垂直电商APP后台系统的FGC进行深度优化(定制JVM参数模版) 3.不合理设置JVM参数可能导致频繁FGC(优化反射的软引用被每次YGC回收) 4.线上系统每天数十次FGC导致频繁卡顿的优化(大对象问题…

电脑找不到mfc110.dll文件要如何解决?Windows缺失mfc110.dll文件快速解决方法

一、mfc110.dll文件的重要性 mfc110.dll&#xff0c;全称Microsoft Foundation Class Library 110&#xff0c;是Microsoft Visual C Redistributable for Visual Studio 2012的一部分。这个动态链接库&#xff08;DLL&#xff09;文件对于支持基于MFC&#xff08;Microsoft F…

《机器学习》——数据标准化(0~1标准化,z标准化)

文章目录 数据标准化一、什么是标准化二、常用标准化0~1标准化z标准化 三、注意事项 数据标准化 一、什么是标准化 数据标准化是一种数据预处理技术&#xff0c;用于将数据按照一定的规则进行变换&#xff0c;使得不同特征或变量具有可比性和一致性。作用 消除量纲影响 在实际…

【Vim Masterclass 笔记02】第3章:Vim 核心知识 + L08:Vim 核心浏览命令 + L09:Vim 核心浏览命令同步练习

文章目录 Section 3&#xff1a;Vim Essentials&#xff08;Vim 核心知识&#xff09;S03L08 Essential Navigation Commands1 光标的上下左右移动2 上 / 下翻页3 基于单词前移4 基于单词后移5 重新定位视图中的文本&#xff08;页面重绘&#xff09;6 定位到所在行的行首7 光标…

2025工作管理综合指南:Jira、Confluence等Atlassian工具套件在工作管理中的应用

在高效的工作场所中&#xff0c;沟通、协作与协调是驱动团队效能与生产力提升的核心要素。企业需构建无缝信息流、顺畅的交接与标准化的流程&#xff0c;以确保无论团队采用何种工作模式——面对面、远程或混合——都能实现高效运作。一套强大的工作管理解决方案&#xff0c;作…

MyBatis-plus sql拦截器

因为业务需求&#xff0c;重新写了一套数据权限。项目中用的是mybtis-plus&#xff0c;正好MyBatis-Plus提供了插件数据权限插件 | MyBatis-Plus&#xff0c;那就根据文档来实现这个需求。 实现&#xff1a; 实现MultiDataPermissionHandler 首先创建MultiDataPermissionHan…

vue导入导出excel、设置单元格文字颜色、背景色、合并单元格(使用xlsx-js-style库)

npm i xlsx-js-style <template><button click"download">下载 Excel 表格</button><el-table :data"tableData" style"width: 100%"><el-table-column prop"date" label"日期" width"180…

Ansys Discovery 中的网格划分方法:探索模式

本篇博客文章将介绍 Ansys Discovery 中可用于在探索模式下进行分析的网格划分方法。我们将在下一篇博客中介绍 Refine 模式下的网格划分技术。 了解 Discovery Explore 模式下的网格划分 网格划分是将几何模型划分为小单元以模拟系统在不同条件下的行为的过程。这是通过创建…

Android布局layout的draw简洁clipPath实现圆角矩形布局,Kotlin

Android布局layout的draw简洁clipPath实现圆角矩形布局&#xff0c;Kotlin 通常&#xff0c;如果要把一个相对布局&#xff0c;FrameLayout&#xff0c;或者线性布局等这样的布局变成具有圆角或者圆形的布局&#xff0c;需要增加一个style&#xff0c;给它设置圆角&#xff0c;…

【中间件】docker+kafka单节点部署---zookeeper模式

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言消息中间件介绍1. KRaft模式2. zookeeper模式2.1. 单节点部署安装验证 前言 最近生产环境上准备部署ELFK日志监控&#xff0c;先在测试环境部署单节点kafka验证…