控制反转(IoC)和依赖注入(DI)实现及常用注解
在Spring框架里,控制反转(IoC)和依赖注入(DI)是核心特性,以下将介绍实现它们的各种方式以及常用注解。
配置文件方式
详细版:
Spring IoC与DI详解:从Bean概念到手写实现
XML 配置
XML 配置是 Spring 早期实现 IoC 和 DI 的主要方式,通过 <bean> 标签定义 Bean,使用不同的属性和子标签来完成依赖注入。
1. Bean 定义与基本属性
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><!-- 定义一个 Bean,id 是唯一标识,class 是该 Bean 对应的类 --><bean id="userService" class="com.example.service.UserService"><!-- 可以通过 init-method 和 destroy-method 指定 Bean 的初始化和销毁方法 --><property name="initMethod" value="init"/><property name="destroyMethod" value="destroy"/></bean>
</beans>
在上述示例中,id 是 Bean 在 Spring 容器中的唯一标识,class 指定了该 Bean 对应的 Java 类。init-method 和 destroy-method 可以让开发者在 Bean 初始化和销毁时执行特定的方法。
2. 构造函数注入
<bean id="userService" class="com.example.service.UserService"><!-- 通过 constructor-arg 标签进行构造函数注入 --><constructor-arg ref="userDao"/>
</bean>
<bean id="userDao" class="com.example.dao.UserDaoImpl"/>
constructor-arg 标签用于向构造函数传递参数,ref 属性表示引用另一个 Bean。这里 UserService 的构造函数接收一个 UserDao 类型的参数,通过 ref 引用了 userDao 这个 Bean。
3. Setter 方法注入
<bean id="userService" class="com.example.service.UserService"><!-- 通过 property 标签进行 Setter 方法注入 --><property name="userDao" ref="userDao"/>
</bean>
<bean id="userDao" class="com.example.dao.UserDaoImpl"/>
property 标签用于调用 Setter 方法注入依赖,name 属性指定要注入的属性名,ref 引用另一个 Bean。
4. 自动装配
<bean id="userService" class="com.example.service.UserService" autowire="byType"/>
<bean id="userDao" class="com.example.dao.UserDaoImpl"/>
autowire 属性可以指定自动装配模式,常见的有 byName(按属性名匹配)、byType(按类型匹配)等。上述示例中,userService 会根据 byType 模式自动注入 UserDao 类型的 Bean。
注解方式
先列出表格:
| 类别 | 注解 | 作用 | 使用示例 | 注意事项 |
|---|---|---|---|---|
| 组件定义注解 | @Component | 通用注解,将类标记为Spring组件,Spring自动扫描并纳入容器管理 | java<br>@Component<br>public class GeneralComponent {<br> // 类的具体实现<br>}<br> | 无 |
@Service | @Component的特化注解,标记业务逻辑层类 | java<br>@Service<br>public class UserService {<br> public void handleBusiness() {<br> // 业务逻辑处理<br> }<br>}<br> | 无 | |
@Repository | @Component的特化注解,标记数据访问层类,还可进行数据访问异常转换 | java<br>@Repository<br>public class UserDaoImpl implements UserDao {<br> public User findById(Long id) {<br> // 根据ID查找用户的逻辑<br> return null;<br> }<br>}<br> | 无 | |
@Controller | @Component的特化注解,标记Spring MVC控制器类,处理HTTP请求 | java<br>@Controller<br>@RequestMapping("/user")<br>public class UserController {<br> @GetMapping("/info")<br> @ResponseBody<br> public String getUserInfo() {<br> return "User Info";<br> }<br>}<br> | 需结合Spring MVC相关注解使用 | |
| 依赖注入注解 | @Autowired | Spring提供的自动装配注解,默认按类型装配,可用于字段、构造函数、Setter方法 | java<br>@Component<br>public class UserController {<br> @Autowired<br> private UserService userService;<br>}<br> | 存在多个相同类型Bean时会有歧义,需结合@Qualifier使用 |
@Qualifier | 与@Autowired配合,当存在多个相同类型Bean时,指定要注入的Bean名称 | java<br>@Component<br>public class UserController {<br> @Autowired<br> @Qualifier("specificUserService")<br> private UserService userService;<br>}<br> | @Qualifier中的名称要与目标Bean的名称一致 | |
@Resource | JSR - 250规范注解,默认按名称注入,未指定名称则按类型注入 | java<br>@Component<br>public class UserController {<br> @Resource(name = "userService")<br> private UserService userService;<br>}<br> | 无 | |
@Inject | JSR - 330规范注解,功能类似@Autowired | java<br>import javax.inject.Inject;<br>@Component<br>public class UserController {<br> @Inject<br> private UserService userService;<br>}<br> | 需要引入JSR - 330相关依赖 | |
| 配置类注解 | @Configuration | 标记Java配置类,类中可用@Bean定义Bean | java<br>@Configuration<br>public class AppConfig {<br> @Bean<br> public UserService userService() {<br> return new UserService();<br> }<br>}<br> | 无 |
@Bean | 在@Configuration类的方法上使用,方法返回值作为Bean注册到容器 | java<br>@Configuration<br>public class AppConfig {<br> @Bean<br> public UserDao userDao() {<br> return new UserDaoImpl();<br> }<br>}<br> | 方法名可作为Bean的默认名称,可在方法中进行复杂初始化操作 |
组件定义注解
这些注解用于将类标记为 Spring 组件,让 Spring 容器自动扫描并管理这些类。
1. @Component
import org.springframework.stereotype.Component;@Component
public class UserService {// 类的具体实现public void doSomething() {System.out.println("UserService is doing something.");}
}
@Component 是一个通用的组件注解,被标记的类会被 Spring 容器识别并创建为 Bean。
2. @Service
import org.springframework.stereotype.Service;@Service
public class UserService {// 业务逻辑实现public void saveUser() {// 保存用户的业务逻辑}
}
@Service 是 @Component 的特化注解,通常用于标记业务逻辑层的类,语义更加明确,方便代码的阅读和维护。
3. @Repository
import org.springframework.stereotype.Repository;@Repository
public class UserDaoImpl implements UserDao {// 数据访问实现public User findUserById(Long id) {// 根据 ID 查询用户的逻辑return null;}
}
@Repository 同样是 @Component 的特化注解,主要用于标注数据访问层的类。Spring 还会对标注了 @Repository 的类进行数据访问异常的转换,方便统一处理异常。
4. @Controller
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;@Controller
@RequestMapping("/user")
public class UserController {// 处理请求的方法@GetMapping("/hello")@ResponseBodypublic String sayHello() {return "Hello, User!";}
}
@Controller 是 @Component 的特化注解,用于标记 Spring MVC 的控制器类,负责处理 HTTP 请求。
依赖注入注解
这些注解用于实现依赖的自动注入,减少手动配置的工作量。
1. @Autowired
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;@Component
public class UserController {// 字段注入@Autowiredprivate UserService userService;// 构造函数注入private UserDao userDao;@Autowiredpublic UserController(UserDao userDao) {this.userDao = userDao;}// Setter 方法注入private AnotherService anotherService;@Autowiredpublic void setAnotherService(AnotherService anotherService) {this.anotherService = anotherService;}
}
@Autowired 可以用于字段、构造函数和 Setter 方法,默认按类型进行自动装配。如果存在多个相同类型的 Bean,可能会出现注入歧义,需要结合 @Qualifier 注解使用。
2. @Qualifier
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;@Component
public class UserController {@Autowired@Qualifier("specificUserService")private UserService userService;// 其他代码
}
当存在多个相同类型的 Bean 时,@Qualifier 用于指定要注入的 Bean 的名称,解决注入歧义问题。
3. @Resource
import javax.annotation.Resource;
import org.springframework.stereotype.Component;@Component
public class UserController {// 按名称注入@Resource(name = "userService")private UserService userService;// 按类型注入@Resourceprivate UserDao userDao;
}
@Resource 是 JSR - 250 规范中的注解,默认按名称注入,如果未指定名称,则按类型注入。
4. @Inject
import javax.inject.Inject;
import org.springframework.stereotype.Component;@Component
public class UserController {@Injectprivate UserService userService;// 其他代码
}
@Inject 是 JSR - 330 规范中的注解,功能和 @Autowired 类似,用于依赖注入。
配置类注解
这些注解用于通过 Java 代码定义 Bean 和配置 Spring 容器。
1. @Configuration
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class AppConfig {@Beanpublic UserService userService() {return new UserService();}@Beanpublic UserDao userDao() {return new UserDaoImpl();}
}
@Configuration 用于标记一个类为 Java 配置类,该类中的方法可以使用 @Bean 注解定义 Bean。
2. @Bean
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class AppConfig {@Beanpublic UserService userService() {// 可以在这里进行复杂的初始化操作UserService userService = new UserService();userService.setUserDao(userDao());return userService;}@Beanpublic UserDao userDao() {return new UserDaoImpl();}
}
@Bean 注解用于在 @Configuration 类的方法上,方法的返回值会被注册到 Spring 容器中作为一个 Bean。开发者可以在方法中进行复杂的初始化操作。
通过以上这些配置文件和注解方式,Spring 框架提供了丰富多样的手段来实现控制反转和依赖注入,开发者可以根据项目的实际情况灵活选择和组合使用。
相关文章:
控制反转(IoC)和依赖注入(DI)实现及常用注解
在Spring框架里,控制反转(IoC)和依赖注入(DI)是核心特性,以下将介绍实现它们的各种方式以及常用注解。 配置文件方式 详细版: Spring IoC与DI详解:从Bean概念到手写实现 XML 配置…...
DeepSeek 接入 Excel 完整教程
一、前期准备 1.1 获取 DeepSeek API 密钥 注册 DeepSeek 平台 访问 DeepSeek 官方网站(或指定的 API 服务平台,如硅基流动等)。若尚未注册,按照平台指引创建新账号并完成登录。 创建 API 密钥 进入用户控制面板,找到…...
林纳斯·托瓦兹:Linux系统之父 Git创始人
名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 林纳斯托瓦兹:Linux之父、Git创始人 一、传奇人物的诞生 1. 早年生活与家…...
8. RabbitMQ 消息队列 + 结合配合 Spring Boot 框架实现 “发布确认” 的功能
8. RabbitMQ 消息队列 结合配合 Spring Boot 框架实现 “发布确认” 的功能 文章目录 8. RabbitMQ 消息队列 结合配合 Spring Boot 框架实现 “发布确认” 的功能1. RabbitMQ 消息队列 结合配合 Spring Boot 框架实现 “发布确认” 的功能1.1 回退消息 2.备用交换机3. API说…...
维港首秀!沃飞长空AE200亮相香港特别行政区
4月13日-16日,第三届香港国际创科展在香港会议展览中心盛大举办。 作为国内领先、国际一流的eVTOL主机厂,沃飞长空携旗下AE200批产构型登陆国际舞台,以前瞻性的创新技术与商业化应用潜力,吸引了来自全球17个国家及地区的行业领袖…...
ffmpeg命令(一):信息查询命令
媒体文件信息查看 命令说明ffmpeg -i input.mp4查看媒体文件基本信息(封装格式、编解码器、时长等)ffprobe input.mp4使用专用工具查看详细信息ffprobe -v error -show_format -show_streams input.mp4输出格式和流的详细信息ffprobe -v quiet -print_f…...
redis6.2.6-prometheus监控
一、软件及系统信息 redis:redis-6.2.6 redis_exporter:redis_exporter-v1.50.0.linux-amd64.tar.gz # cat /etc/anolis-release Anolis OS release 8.9 granfa; 7.5.3 二、下载地址 https://github.com/oliver006/redis_exporter/releases?page…...
MCP认证难题破解指南
一、MCP 认证体系与核心挑战 1.1 认证体系解析 MCP(Microsoft Certified Professional)作为微软认证体系的基础,覆盖操作系统、云服务、开发工具等核心领域。2025 年最新认证体系包含以下关键方向: Azure 云服务: 覆盖 Azure 虚拟机、容器化部署、云原生应用开发等核心技…...
20250415-vue-插槽-默认内容
在外部没有提供任何内容的情况下,可以为插槽指定默认内容。比如有这样一个 <SubmitButton> 组件: <button type"submit"><slot></slot> </button> 如果我们想在父组件没有提供任何插槽内容时再 <button> 内渲染 “…...
Ubuntu离线安装搜狗输入法
1. 下载输入法 下载搜狗输入法 2. 在联网的Ubuntu下载依赖 在联网的ubuntu上下载依赖 创建脚本download.sh mkdir deb-packages cd deb-packages packages"fcitx fcitx-libs libegl-dev libgl-dev libglu1-mesa-dev libglx-dev libgrpc1 libgrpc6 libjsoncpp1 libnss-…...
如何在idea中快速搭建一个Spring Boot项目?
文章目录 前言1、创建项目名称2、勾选需要的依赖3、在setting中检查maven4、编写数据源5、开启热启动(热部署)结语 前言 Spring Boot 凭借其便捷的开发特性,极大提升了开发效率,为 Java 开发工作带来诸多便利。许多大伙伴希望快速…...
itext7 html2pdf 将html文本转为pdf
1、将html转为pdf需求分析 经常会看到爬虫有这样的需求,将某一个网站上的数据,获取到了以后,进行分析,然后将需要的数据进行存储,也有将html转为pdf进行存储,作为原始存档,当然这里看具体的需求…...
边缘计算场景下的模型轻量化:TensorRT部署YOLOv7的端到端优化指南
一、边缘计算场景下的技术挑战与优化路径 在边缘设备(如Jetson系列)部署YOLOv7需兼顾模型精度、推理速度与功耗限制三重约束。TensorRT作为NVIDIA官方推理加速库,通过算子融合、量化压缩和内存复用等优化技术,可将模型推理速度提…...
golang 在windows 系统的交叉编译
基本交叉编译命令 GOOS目标操作系统 GOARCH目标架构 go build -o 输出文件名 包路径 编译 Linux 64位程序 set GOOSlinux set GOARCHamd64 go build -o myapp-linux main.go 编译 MacOS (Darwin) 64位程序 set GOOSdarwin set GOARCHamd64 go build -o myapp-macos main.go …...
docker compose搭建博客wordpress
一、前言 docker安装等入门知识见我之前的这篇文章 https://blog.csdn.net/m0_73118788/article/details/146986119?fromshareblogdetail&sharetypeblogdetail&sharerId146986119&sharereferPC&sharesourcem0_73118788&sharefromfrom_link 1.1 docker co…...
VueDOMPurifyHTML 防止 XSS(跨站脚本攻击) 风险
VueDOMPurifyHTML 是一个 Vue.js 插件,用于在 v-html 指令中安全地渲染 HTML 内容,防止 XSS(跨站脚本攻击) 风险。 作用 解决 v-html 的安全问题 Vue 的 v-html 会直接渲染原始 HTML࿰…...
代码随想录算法训练营Day30
力扣452.用最少数量的箭引爆气球【medium】 力扣435.无重叠区间【medium】 力扣763.划分字母区间【medium】 力扣56.合并区间【medium】 一、力扣452.用最少数量的箭引爆气球【medium】 题目链接:力扣452.用最少数量的箭引爆气球 视频链接:代码随想录 题…...
国内开源医疗模型研究报告
引言 随着人工智能技术的快速发展,医疗AI领域正经历前所未有的变革。开源医疗模型作为这一领域的核心技术基础设施,不仅推动了医疗智能化进程,也为医疗工作者提供了强大的辅助工具。本报告将深入探讨国内优秀的开源医疗模型,分析…...
无感改造,完美监控:Docker 多阶段构建 Go 应用无侵入观测
作者:牧思 背景 随着云原生的普及,Golang 编程语言变得越来越热门。相比 Java,Golang 凭借其轻量,易学习的特点得到了越来越多工程师的青睐,然而由于 Golang 应用需要被编译成二进制文件再进行运行,Golan…...
音乐产业新玩法:NFTs如何颠覆传统与挑战未来?
音乐产业新玩法:NFTs如何颠覆传统与挑战未来? 近年来,NFT(Non-Fungible Token,非同质化代币)像一颗新星,迅速在数字艺术、游戏等领域掀起了革命。而在音乐产业,NFT不仅是一种数字所…...
006.Gitlab CICD流水线触发
文章目录 触发方式介绍触发方式类型 触发方式实践分支名触发MR触发tag触发手动人为触发定时任务触发指定文件变更触发结合分支及文件变更触发正则语法触发 触发方式介绍 触发方式类型 Gitlab CICD流水线的触发方式非常灵活,常见的有如下几类触发方式: …...
512天,倔强生长:一位技术创作者的独白
亲爱的读者与同行者: 我是倔强的石头_,今天是我在CSDN成为创作者的第512天。当系统提示我写下这篇纪念日文章时,我恍惚间想起了2023年11月19日的那个夜晚——指尖敲下《开端——》的标题,忐忑又坚定地按下了“发布”键。那时的我…...
【目标检测】【YOLO综述】YOLOv1到YOLOv10:最快速、最精准的实时目标检测系统
YOLOv1 to YOLOv10: The fastest and most accurate real-time object detection systems YOLOv1到YOLOv10:最快速、最精准的实时目标检测系统 论文链接 0.论文摘要 摘要——本文是对YOLO系列系统的全面综述。与以往文献调查不同,本综述文…...
青少年编程与数学 02-016 Python数据结构与算法 16课题、贪心算法
青少年编程与数学 02-016 Python数据结构与算法 16课题、贪心算法 一、贪心算法的基本概念定义组成部分 二、贪心算法的工作原理三、贪心算法的优点四、贪心算法的缺点五、贪心算法的应用实例(一)找零问题(二)活动安排问题&#x…...
日常学习开发记录-slider组件
日常学习开发记录-slider组件 从零开始实现一个优雅的Slider滑块组件前言一、基础实现1. 组件结构设计2. 基础样式实现3. 基础交互实现 二、功能增强1. 添加拖动功能2. 支持范围选择3. 添加垂直模式 三、高级特性1. 键盘操作支持2. 禁用状态 五、使用示例六、总结 从零开始实现…...
Windows 系统如何使用Redis 服务
前言 在学习过程中,我们长期接触到的是Mysql 关系型数据库,也是够我们平时练习项目用的,但是后面肯定会有大型数据的访问就要借助新的新的工具。 一、什么是Redis Redis(Remote Dictionary Server)是一个基于内存的 键…...
【unity游戏开发入门到精通——UGUI】CanvasScaler画布缩放器组件
注意:考虑到UGUI的内容比较多,我将UGUI的内容分开,并全部整合放在【unity游戏开发——UGUI】专栏里,感兴趣的小伙伴可以前往逐一查看学习。 文章目录 一、CanvasScaler画布缩放器组件是什么二、CanvasScaler的三种适配模式1、Cons…...
Hugging Face 模型:AI 模型的“拥抱”与开源革命!!!
🌐 Hugging Face 模型:AI 模型的“拥抱”与开源革命 用表情符号、图表和代码,探索开源模型生态的底层逻辑与应用场景! 🌟 名字由来:为什么叫 Hugging Face? “Hugging”:象征 开放…...
关于 人工智能(AI)发展简史 的详细梳理,按时间阶段划分,涵盖关键里程碑、技术突破、重要人物及挑战
以下是关于 人工智能(AI)发展简史 的详细梳理,按时间阶段划分,涵盖关键里程碑、技术突破、重要人物及挑战: 字数:约2500字 逻辑结构:时间线清晰,分阶段描述技术突破、关键事件与挑战…...
微服务即时通信系统---(四)框架学习
目录 ElasticSearch 介绍 安装 安装kibana ES客户端安装 头文件包含和编译时链接库 ES核心概念 索引(Index) 类型(Type) 字段(Field) 映射(mapping) 文档(document) ES对比MySQL Kibana访问ES测试 创建索引库 新增数据 查看并搜索数据 删除索引 ES…...
