【Spring】Spring DI(依赖注入)详解——自动装配——手动装配与自动装配的区别

在spring开发中,依赖注入(Dependency Injection,DI)是实现松耦合和高内聚设计的重要模式。它使得对象的创建和管理与其依赖关系分离,从而提高了代码的可维护性、可测试性和灵活性。Spring框架通过IoC(控制反转)容器来实现DI,提供了多种方式来管理对象的依赖关系。

在实际开发中,我们经常需要在不同的类之间进行依赖注入,这就引出了手动装配和自动装配的概念。手动装配需要开发者显式地配置每个依赖,而自动装配则让Spring容器根据一定的规则自动注入依赖。 比如,你在一个餐厅点餐。手动装配就像是你亲自选择每一道菜,告诉服务员你想要的具体菜品;而自动装配则像是服务员根据你的口味和偏好,自动为你推荐并准备好一整套套餐。手动装配虽然灵活,但需要更多的时间和精力,而自动装配则简化了流程,提高了效率。

一、手动装配与自动装配的区别
1. 手动装配

手动装配是指开发者需要在配置文件或代码中明确指定每个依赖的创建和注入。开发者需要清楚每个Bean的依赖关系,并手动进行配置。

优点

  • 完全控制依赖的创建过程。

  • 适合复杂的依赖关系或需要特定配置的场景。

缺点

  • 配置繁琐,增加了维护成本。

  • 难以应对依赖关系的变化。

2. 自动装配

自动装配是指Spring容器根据一定的规则自动注入依赖。Spring提供了多种自动装配的方式,其中最常用的是byName和byType。

  • byName:根据Bean的名称进行匹配。

  • byType:根据Bean的类型进行匹配。

优点

  • 减少了配置的复杂性。

  • 更加灵活,适应性强。

缺点

  • 可能会引入不必要的依赖,增加调试难度。

  • 对于多个同类型的Bean,可能导致冲突。

二、自动装配的实现方式

下面我们通过具体示例来演示自动装配的实现,分别介绍byName和byType的方式。

1. 创建服务和依赖类

首先,我们定义两个服务类UserServiceOrderService,其中OrderService依赖于UserService

// UserService.java
public class UserService {public void registerUser() {System.out.println("User registered successfully.");}
}// OrderService.java
public class OrderService {private UserService userService;// 通过Setter方法注入UserServicepublic void setUserService(UserService userService) {this.userService = userService;}public void placeOrder() {System.out.println("Order placed.");userService.registerUser(); // 调用UserService的方法}
}

解释

  • UserService类负责用户注册逻辑。

  • OrderService类依赖于UserService,通过Setter方法进行注入。

2. 手动装配的实现

我们首先实现手动装配的方式,通过Spring的Java配置来创建这些Bean。

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;@Configuration
public class ManualConfig {@Beanpublic UserService userService() {return new UserService(); // 创建UserService实例}@Beanpublic OrderService orderService() {OrderService orderService = new OrderService();orderService.setUserService(userService()); // 手动注入UserServicereturn orderService;}
}

解释

  • ManualConfig类是手动装配的配置类,使用@Bean注解定义Bean。

  • orderService()方法中显式调用setUserService()进行依赖注入。

3. 自动装配的实现

接下来,我们使用自动装配的方式来实现同样的功能。

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.stereotype.Component;@Configuration
@ComponentScan(basePackages = "com.example") // 自动扫描指定包中的组件
public class AutoConfig {@Beanpublic UserService userService() {return new UserService(); // 创建UserService实例}
}// 使用@Component注解标记OrderService为Spring管理的组件
@Component
public class OrderService {private UserService userService;// 自动装配UserService(byType)public OrderService(UserService userService) {this.userService = userService;}public void placeOrder() {System.out.println("Order placed.");userService.registerUser(); // 调用UserService的方法}
}

解释

  • @ComponentScan注解用于自动扫描指定包中的组件。

  • OrderService类使用构造器注入的方式自动装配UserService,Spring会根据类型自动匹配。

4. 启动应用

最后,我们创建一个主类来启动Spring应用并获取OrderService Bean。

public class Main {public static void main(String[] args) {// 创建Spring容器ApplicationContext context = new AnnotationConfigApplicationContext(AutoConfig.class);// 获取OrderService BeanOrderService orderService = context.getBean(OrderService.class);orderService.placeOrder(); // 调用下订单的方法}
}

解释

  • AnnotationConfigApplicationContext用于创建基于Java配置的Spring容器。

  • 通过context.getBean(OrderService.class)获取OrderService的实例,并调用其placeOrder()方法。

三、总结

手动装配和自动装配是Spring中依赖注入的两种重要方式。手动装配提供了对依赖关系的完全控制,但配置繁琐;而自动装配则简化了配置过程,提高了开发效率,但可能引入不必要的复杂性。

通过本次讲解,我们深入理解了自动装配的byName和byType方式,以及手动装配的实现。掌握这些知识将帮助我们在实际项目中更灵活地管理对象之间的依赖关系,提升代码的可维护性和可测试性。

希望通过这次的学习,能够帮助你在Java开发中更好地应用Spring框架的依赖注入特性。在实际开发中,可以根据具体的需求和场景选择合适的装配方式。

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

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

相关文章

EZ-USB™ FX3 USB 5 Gbps 外设控制器

EZ-USB™ FX3 USB 5 Gbps 外设控制器 EZ-USB™ FX3 提供 USB 5Gbps 至 32 位数据总线,并配备 ARM9,可为任何系统添加 USB 3.0 连接 英飞凌的 EZ-USB™ FX3 是业界用途最广泛的 USB 外围设备控制器,可以为几乎任何系统添加 USB 5Gbps 连接。 …

【数据仓库】spark大数据处理框架

文章目录 概述架构spark 架构角色下载安装启动pyspark启动spark-sehll启动spark-sqlspark-submit经验 概述 Spark是一个性能优异的集群计算框架,广泛应用于大数据领域。类似Hadoop,但对Hadoop做了优化,计算任务的中间结果可以存储在内存中&a…

数据库容灾备份的意义+分类+执行工具!

数据库容灾解决方案的背景 数据库容灾(Disaster Recovery,DR)解决方案的背景主要源于企业对数据安全性、业务连续性和系统高可用性的需求。随着数字化转型的加速,企业的数据量迅猛增长,数据库已成为支撑核心业务的关键…

PDF怎么压缩得又小又清晰?5种PDF压缩方法

PDF 文件在日常办公与学习中使用极为频繁,可想要把它压缩得又小又清晰却困难重重。一方面,PDF 格式本身具有高度兼容性,集成了文字、图像、矢量图等多样元素,压缩时难以兼顾不同元素特性,稍不注意,文字就会…

GoldenDB组件及对应的用户和进程

1. GoldenDB组件及对应的用户和进程 GoldenDB数据库由管理节点、全局事务节点GTM、计算节点CN、数据节点DN等组成。 1.1. 管理节点 管理节点分为集群管理、Insight运维管理平台(InsightServer、RDB、ZK)。 1.1.1. 集群管理 1. 集群管理包括Metadatas…

OpenStack系列第四篇:云平台基础功能与操作(Dashboard)

文章目录 1. 镜像(Image)添加镜像查看镜像删除镜像 2. 卷(Volume)创建卷查看卷删除卷 3. 网络(虚拟网络)创建网络查看网络删除网络 4. 实例类型创建实例类型查看实例类型删除实例类型 4. 密钥对&#xff08…

CSDN编辑器

这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个…

四大自平衡树对比:AVL树、红黑树、B树与B+树

AVL树、红黑树、B树和B树的对比与应用场景 树系列相关文章(置顶) 1、从链表到平衡树:二叉查找树的退化与优化 2、自平衡二叉查找树:如何让二叉查找树始终保持高效 3、AVL树入门:理解自平衡二叉查找树的基础 4、红黑树全…

Linux下读取Windows下保存的文件,报错信息中出现“^M“时如何解决?【由于Windows和Linux的换行方式不同造成的-提供两种转换方式】

Windows 和 Linux 的文本文件使用的换行符不同: Windows 使用 \r\n (回车 换行)。Linux 使用 \n (换行)。 因此,当在 Linux 系统上运行带有 Windows 换行符的脚本或读取相关文件时,可能会出现…

npm ERR! ECONNRESET 解决方法

问题:npm 命令遇到的错误是 ECONNRESET,这通常与网络连接问题相关。设置代理解决问题。 一、查看当前代理设置 npm config get proxy npm config get https-proxy二、设置代理 npm config set proxy http://your-proxy-address:port npm config set h…

【UE5】UnrealEngine源码构建2:windows构建unreal engine 5.3.2

参考大神知乎的文章:UE5 小白也能看懂的源码编译指南 据说会耗费400G的空间。 代码本身并不大,可能是依赖特别多,毕竟看起来UE啥都能干,核心还是c++的, 【UE5】UnrealEngine源码构建1:tag为5.3.2源码clone 本着好奇+ 学习的态度,想着也许有机会能更为深入的熟悉UE的机制…

在Linux上获取MS(如Media Server)中的RTP流并录制为双轨PCM格式的WAV文件

在Linux上获取MS(如Media Server)中的RTP流并录制为双轨PCM格式的WAV文件 一、RTP流与WAV文件格式二、实现步骤三、伪代码示例四、C语言示例代码五、关键点说明六、总结在Linux操作系统上,从媒体服务器(如Media Server,简称MS)获取RTP(Real-time Transport Protocol)流…

Vue3 简介

Vue3 简介 最新版本: v3.5.13 1、性能提升 打包大小减少 41% - 初次渲染快 55%, 更新渲染快 133%内存减少 54% 2、源码的升级 使用 Proxy 代替 defineProperty 实现响应式。重写虚拟 DOM 的实现和 Tree-Shaking 3、拥抱TypeScript Vue3 可以更好的支持 TypeSc…

Oracle Dataguard(主库为 Oracle 11g 单节点)配置详解(1):Oracle Dataguard 概述

Oracle Dataguard(主库为 Oracle 11g 单节点)配置详解(1):Oracle Dataguard 概述 目录 Oracle Dataguard(主库为 Oracle 11g 单节点)配置详解(1):Oracle Data…

北京某新能源汽车生产及办公网络综合监控项目

北京某新能源汽车是某世界500强汽车集团旗下的新能源公司,也是国内首个获得新能源汽车生产资质、首家进行混合所有制改造、首批践行国有控股企业员工持股的新能源汽车企业,其主营业务包括纯电动乘用车研发设计、生产制造与销售服务。 项目现状 在企业全…

大数据系列之:深入理解学习使用腾讯COS和COS Ranger权限体系解决方案,从hdfs同步数据到cos

大数据系列之:深入理解学习使用腾讯COS和COS Ranger权限体系解决方案,从hdfs同步数据到cos 对象存储COS对象存储基本概念COS Ranger权限体系解决方案部署组件COS Ranger Plugin部署COS-Ranger-Service部署COS Ranger Client部署 COSN 从hdfs同步数据到co…

1月第一讲:WxPython跨平台开发框架之前后端结合实现附件信息的上传及管理

1、功能描述和界面 前端(wxPython GUI): 提供文件选择、显示文件列表的界面。支持上传、删除和下载附件。展示上传状态和附件信息(如文件名、大小、上传时间)。后端(REST API 服务)&#xff1a…

12.29~12.31[net][review]need to recite[part 2]

网络层 IP 首部的前一部分是固定长度,共 20 字节,是所有 IP 数据报必须具有的 路由器 路由选择协议属于网络层控制层面的内容 l 路由器 的 主要工作: 转发分组。 l 路由 信息协议 RIP (Routing Information Protocol ) 是 一种 分布式的…

免费下载 | 2024网络安全产业发展核心洞察与趋势预测

《2024网络安全产业发展核心洞察与趋势预测》报告的核心内容概要: 网络安全产业概况: 2023年中国网络安全产业市场规模约992亿元,同比增长7%。 预计2024年市场规模将增长至1091亿元,2025年达到1244亿元。 网络安全企业数量超过4…

记忆旅游系统|Java|SSM|VUE| 前后端分离

【技术栈】 1⃣️:架构: B/S、MVC 2⃣️:系统环境:Windowsh/Mac 3⃣️:开发环境:IDEA、JDK1.8、Maven、Mysql5.7 4⃣️:技术栈:Java、Mysql、SSM、Mybatis-Plus、VUE、jquery,html 5⃣️数据库可…