一文彻底弄懂Spring IOC 依赖注入
Spring IOC(Inversion of Control,控制反转)依赖注入是 Spring 框架的核心特性之一,旨在实现对象之间的松耦合,提升代码的可维护性、可测试性和可扩展性。下面我们将从以下几个方面深入探讨 Spring IOC 依赖注入的机制和实现原理。
一、基本概念
控制反转(Inversion of Control)
控制反转是一种设计原则,指的是将对象的创建和管理职责从应用程序中转移到框架中。传统上,应用程序直接创建依赖对象,而在 IOC 中,控制权由容器掌握,应用只需声明所需的依赖。
依赖注入(Dependency Injection)
依赖注入是实现控制反转的一种具体方式,通过构造函数、setter 方法或字段注入,将依赖的对象传递给使用它的对象。
二、依赖注入的实现方式
Spring 提供了三种主要的依赖注入方式:
构造器注入
通过构造函数传入依赖对象,通常适用于需要强制依赖的情况。
示例:
public class UserService {
private final UserRepository userRepository; public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
}
Setter 注入
通过 setter 方法设置依赖对象,适合可选依赖的场景。
示例:
public class UserService {
private UserRepository userRepository; public void setUserRepository(UserRepository userRepository) {
this.userRepository = userRepository;
}
}
字段注入
直接在字段上使用
@Autowired
注解,Spring 会自动注入依赖。此方式适用于简单场景,但不利于单元测试。示例:
public class UserService {
@Autowired
private UserRepository userRepository;
}
三、Spring IOC 容器的工作原理
Bean 定义
在 Spring 中,每个被管理的对象称为 Bean。Bean 的定义通常通过 XML 配置文件或 Java 注解(如
@Component
,@Service
,@Repository
,@Controller
等)来描述。容器初始化
当 Spring 容器启动时,它会加载所有的 Bean 定义,创建 Bean 实例,并解析其依赖关系。依赖关系解析的过程主要分为以下几步:
- Bean 创建:通过反射机制创建 Bean 实例。
- 依赖解析:根据配置确定 Bean 的依赖关系,并实例化其依赖 Bean。
- 注入依赖:将依赖对象注入到目标 Bean 中。
生命周期管理
Spring 容器管理 Bean 的生命周期,包括创建、初始化、销毁等过程。开发者可以通过实现
InitializingBean
和DisposableBean
接口或使用@PostConstruct
和@PreDestroy
注解来控制 Bean 的生命周期。
四、依赖注入的优势
松耦合
通过依赖注入,类之间不再直接依赖于具体实现,而是依赖于接口或抽象类,这减少了类之间的耦合度。
可测试性
由于依赖关系通过构造函数或 setter 方法注入,方便进行单元测试。在测试时可以使用模拟对象(Mock)来替代真实的依赖。
灵活性和可扩展性
可以通过更改配置来替换实现,而不需要修改使用该依赖的代码,增强了系统的灵活性。
五、依赖注入的使用场景
服务层与数据访问层
在 Web 应用中,服务层通常依赖于数据访问层的接口,通过依赖注入,可以轻松实现服务与数据访问之间的解耦。
配置与环境管理
可以将环境相关的配置(如数据库连接、消息队列等)抽象为 Bean,通过依赖注入使不同环境下的配置可以灵活切换。
增强模块化
在大型企业应用中,通过依赖注入可以实现模块间的清晰分离,使得各模块可以独立开发和测试。
六、示例代码
以下是一个使用 Spring IOC 依赖注入的简单示例:
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.stereotype.Component;
@Component
class UserRepository {
public void save() {
System.out.println("User saved!");
}
}
@Component
class UserService {
private final UserRepository userRepository;
// 构造器注入
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public void registerUser() {
userRepository.save();
}
}
public class Main {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext("com.example"); // 包名
UserService userService = context.getBean(UserService.class);
userService.registerUser(); // 输出 "User saved!"
}
}
七、深入的设计考虑
AOP(面向切面编程)集成
Spring IOC 依赖注入与 AOP 结合,可以在不修改业务逻辑的情况下,为 Bean 增加横切关注点(如事务管理、日志记录等)。
Bean 的作用域
Spring 支持多种 Bean 作用域,如单例(singleton)、原型(prototype)、请求(request)、会话(session)等,开发者可以根据需要选择合适的作用域。
条件注入
Spring 允许通过条件注解(如
@Conditional
)来实现基于环境或条件的依赖注入,提高配置的灵活性。性能考虑
虽然依赖注入带来了灵活性,但在高性能场景下,要注意对象创建的开销。可以使用单例 Bean 或者通过静态工厂方法来优化性能。
一文彻底弄懂Spring IOC 依赖注入的更多相关文章
- Spring IOC 依赖注入的两种方式XML和注解
依赖注入的原理 依赖注入的方式---XML配置 依赖注入的方式---注解的方式 Spring 它的核心就是IOC和AOP.而IOC中实现Bean注入的实现方式之一就是DI(依赖注入). 一 DI的原理 ...
- 一篇关于spring ioc 依赖注入3种方式的文章引用
今天看到一篇spring ioc 容器依赖注入3种方式的文章,为了方便后面的复习,在此引用别人的文章,查看请戳我.
- java框架篇---spring IOC依赖注入
spring依赖注入的方式有4种 构造方法注入 属性注入 工厂注入 注解注入 下面通过一个实例统一讲解: User.java package com.bjsxt.model; public class ...
- Spring IoC 依赖注入的方法大全 XML配置方式
Spring 依赖注入 构造方法注入 ① 根据索引注入 <bean name="student" class="cn.bdqn.SpringDI.Student ...
- (spring-第3回【IoC基础篇】)spring的依赖注入-属性、构造函数、工厂方法等的注入(基于XML)
Spring要把xml配置中bean的属性实例化为具体的bean,"依赖注入"是关卡.所谓的"依赖注入",就是把应用程序对bean的属性依赖都注入到spring ...
- Spring学习-spring核心机制-IOC依赖注入
转载自:http://www.cnblogs.com/chenssy/archive/2012/11/11/2765266.html 今天复习一下spring两大特性之一:IOC依赖注入,看了一下大佬 ...
- Spring.NET依赖注入框架学习--简介
Spring.NET依赖注入框架学习--Spring.NET简介 概述 Spring.NET是一个应用程序框架,其目的是协助开发人员创建企业级的.NET应用程序.它提供了很多方面的功能,比如依赖注入. ...
- Spring.NET依赖注入框架学习--入门
Spring.NET依赖注入框架学习--入门 在学些Spring.net框架之前,有必要先脑补一点知识,比如什么是依赖注入?IOC又是什么?控制反转又是什么意思?它们与Spring.net又有什么关系 ...
- 使用IDEA详解Spring中依赖注入的类型(上)
使用IDEA详解Spring中依赖注入的类型(上) 在Spring中实现IoC容器的方法是依赖注入,依赖注入的作用是在使用Spring框架创建对象时动态地将其所依赖的对象(例如属性值)注入Bean组件 ...
- IOC依赖注入简单实例
转自:http://hi.baidu.com/xyz136299110/item/a32be4269e9d0c55c38d59e6 相信大家看过相当多的IOC依赖注入的例子. 但大家在没有明白原理的情 ...
随机推荐
- Go 监控告警入门 Opentelemetry
前言 Opentelemetry 分布式链路跟踪( Distributed Tracing )的概念最早是由 Google 提出来的,发展至今技术已经比较成熟,也是有一些协议标准可以参考.目前在 Tr ...
- 嵌入式工程师到底要不要学习ARM汇编指令?arm学习文章汇总
嵌入式工程师到底要不要学习ARM汇编指令? 网上搜索这个问题,答案很多,大部分的建议是不要学汇编,只要学C语言. 而一口君作为一个十几年经验的驱动工程师,个人认为,汇编语言还是需要掌握的,想要搞精.搞 ...
- Go 互斥锁 Mutex 源码分析(二)
原创文章,欢迎转载,转载请注明出处,谢谢. 0. 前言 在 Go 互斥锁 Mutex 源码分析(一) 一文中分析了互斥锁的结构和基本的抢占互斥锁的场景.在学习锁的过程中,看的不少文章是基于锁的状态解释 ...
- 自制 ShareLaTeX 镜像
Overleaf 官方的 sharelatex 镜像的 TeX Live 版本可能较旧,无法安装最新的宏包,并且往往只包含了少量的基础宏包.为了方便使用,我们可以自己构建一个使用最新 TeX Live ...
- 【Python】之操作鼠标键盘,上传文件,并支持中文
Mac系统实现操作键盘 Python中模拟键盘和鼠标最著名的模块是:pymouse和pykeyboard.一次安装两个模块比较麻烦,而有一个库整合了这两个模块,而且能支持跨平台操作,这个库叫PyUse ...
- 2024 NepCTF
NepCTF NepMagic -- CheckIn 直接玩游戏就能出 注意有一关要把隐藏的方块全找到 NepCamera 先使用tshark读取数据 结果文件中发现大量jpeg头ffd8ffe0. ...
- android 反编译APK取源代码。
坑,自己写的Android APK 程序,发现线上版本是 1.9.4 ,本地的代码版本却是 1.9.1.不知道到底怎么回事,svn里面也没有日志记录.....只能从线上apk反编译来看看了,幸好这个升 ...
- git merge 详细操作,看完就懂
[root@hostname git_test]# git init hint: Using 'master' as the name for the initial branch. This def ...
- EF Core – JSON Column
前言 SQL Server 支持 JSON, 以前写过一篇介绍 SQL Server – Work with JSON. 但 EF Core 一直没有支持. 直到 EF Core 7.0 才支持. 参 ...
- 编写自己的简易版网络协议栈(1)--arp协议,使用wireshark抓包分析
实验环境: 略. 实验背景:已编写好基于以太网接口的输入处理,能够解析到以太网数据包内的帧类型. 1. 协议栈底层采用轮询方式,即轮询以太网数据包. 2. 若收到数据,则交由以太网输入处理模块进行解析 ...