别再懵圈了!Spring IOC/DI,看完不懂你喷我!
创作时间:
作者:
@小白创作中心
别再懵圈了!Spring IOC/DI,看完不懂你喷我!
引用
CSDN
1.
https://blog.csdn.net/qq_56158663/article/details/145657694
Spring框架中的IOC(控制反转)和DI(依赖注入)是Java开发中非常重要的概念。本文通过生动的比喻和详细的代码示例,帮助读者深入理解这两个核心概念的定义、作用和应用场景。
一、什么是IOC(控制反转)?
- 传统方式:想象一下,你要盖房子。传统方式是你自己找砖头、水泥、钢筋,自己搅拌水泥,自己一块一块地砌砖。所有的事情都由你来控制😥。
- IOC 方式:现在有了 IOC,你只需要告诉一个建筑公司(IOC 容器):“我要盖房子,需要这些材料和工人。” 建筑公司会帮你准备好一切,你只需要等着房子盖好就行了😎。你不再需要自己控制每一个细节,控制权交给了建筑公司。
- 大白话:IOC 就是把创建对象和管理对象之间依赖关系的权力,从你自己手里转移到了 Spring 容器手里。 你不用自己
new对象,也不用自己管对象之间的关系了,Spring 帮你搞定👍。
二、什么是 DI (依赖注入)?
- 依赖:房子需要砖头、水泥、钢筋,这些就是房子的“依赖”。
- 注入:建筑公司把砖头、水泥、钢筋“注入”到房子里,让房子可以盖起来🧱 🔨。
- 大白话:DI 就是 Spring 容器把你的对象需要的“依赖”(比如其他的对象、配置信息等)自动“注入”到你的对象里。 你不用自己去
new这些依赖,Spring 会自动帮你把它们放到正确的位置🚀。
三、为什么要有 IOC 和 DI?
- 解耦:想象一下,如果房子必须用特定品牌的砖头,那你就被这个品牌的砖头绑死了。 IOC 和 DI 可以让你更容易更换砖头(依赖),而不用修改房子的结构(代码)。
- 可测试性:如果房子里的水管是你自己焊的,那你想测试水管质量就很麻烦😫。 IOC 和 DI 可以让你更容易用模拟的水管(Mock 对象)来测试房子,而不用真的把水管焊上去✅。
- 可维护性:如果房子结构复杂,你自己管理所有的材料和工人,很容易出错🤯。 IOC 和 DI 可以让 Spring 帮你管理,减少你的负担,让代码更清晰易懂✨。
- 简化开发:你不用自己写大量的代码来创建对象和管理依赖关系,Spring 帮你做了很多,你可以更专注于业务逻辑🧘。
注意: IOC是一种设计思想,而DI是实现IOC的一种方式而已
四、IOC 和 DI 的好处
- 降低耦合度:各个组件之间的依赖关系由容器管理,组件之间不需要知道彼此的存在,降低了耦合度⬇️🔗。
- 提高可测试性:可以方便地使用 Mock 对象进行单元测试✅。
- 提高可维护性:代码结构更清晰,易于理解和维护🛠️。
- 提高代码复用性:组件可以被多个应用程序复用♻️。
- 提高开发效率:减少了手动管理对象依赖关系的工作量⚡。
五、应用实例
1. 简单示例:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component // 告诉 Spring Boot 这是一个组件,需要被管理
public class UserService {
@Autowired // 告诉 Spring Boot,我需要一个 UserDao 对象
private UserDao userDao;
public String getUserName(int userId) {
return userDao.getUserNameById(userId);
}
}
@Component
public class UserDao {
public String getUserNameById(int userId) {
// 模拟从数据库获取用户名
return "User-" + userId;
}
}
- 解释:
@Component: 告诉 Spring ,UserService和UserDao是组件,需要被 Spring 管理。@Autowired: 告诉 Spring ,UserService需要一个UserDao对象。 Spring 会自动创建一个UserDao对象,并把它“注入”到UserService中。- 你不需要自己
new UserDao(),Spring 帮你做了。
2. 使用配置文件注入:
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class AppConfig {
@Value("${app.name}") // 从 application.properties 中读取 app.name 的值
private String appName;
public String getAppName() {
return appName;
}
}
- application.properties:
app.name=My Awesome App
- 解释:
@Value: 告诉 Spring,从application.properties文件中读取app.name的值,并把它“注入”到appName变量中。- 你不需要自己读取配置文件,Spring 帮你做了。
3. 使用构造器注入:
import org.springframework.stereotype.Component;
@Component
public class ReportService {
private final DataProvider dataProvider;
// 构造器注入
public ReportService(DataProvider dataProvider) {
this.dataProvider = dataProvider;
}
public String generateReport() {
return "Report: " + dataProvider.getData();
}
}
@Component
class DataProvider {
public String getData() {
return "Some Data";
}
}
- 解释:
ReportService通过构造函数接收DataProvider的实例。- Spring 会自动找到
DataProvider的 Bean,并将其注入到ReportService的构造函数中。 - 构造器注入是推荐的方式,因为它能保证依赖的不可变性,并且更容易进行单元测试。
4. 使用接口和多态:
public interface MessageService {
String getMessage();
}
@Component("emailService")
public class EmailService implements MessageService {
@Override
public String getMessage() {
return "Sending email...";
}
}
@Component("smsService")
public class SMSService implements MessageService {
@Override
public String getMessage() {
return "Sending SMS...";
}
}
@Component
public class NotificationService {
@Autowired
@Qualifier("emailService") // 指定要注入哪个 MessageService
private MessageService messageService;
public void sendNotification() {
System.out.println(messageService.getMessage());
}
}
- 解释:
MessageService是一个接口,EmailService和SMSService是它的实现类。@Qualifier: 告诉 Spring,要注入哪个MessageService的实现类。- 这种方式可以让你更容易切换不同的消息服务,而不用修改
NotificationService的代码。
5. 更复杂的场景:
- AOP (面向切面编程):使用 IOC 和 DI 来管理切面,实现日志记录、权限控制等功能。
- 事务管理:使用 IOC 和 DI 来管理事务,保证数据的一致性。
- 集成其他框架:使用 IOC 和 DI 来集成 MyBatis、Hibernate 等框架。
六、总结
- IOC:就像你把盖房子的事情交给建筑公司,你不用自己管材料和工人了,Spring帮你管🏢。
- DI:就像建筑公司把砖头、水泥自动送到房子里,你不用自己去搬了,Spring帮你送🚚。
- 好处:代码更清晰、更容易修改、更容易测试,你更省心!😊
希望这篇文章能够帮助你理解 Spring中的 IOC 和 DI。 记住,多写代码,多实践,才能真正掌握它们!
热门推荐
白居易的《立秋夕有怀梦得》:句句伤感,字字忧愁,写尽思念好友之情
昆明至景洪机票查询攻略:如何抓住超值特价机票,让旅程更加美好?
大叶女贞树适合种在院内吗
《斗破苍穹》再登腾讯视频动漫榜首:热度与争议并存
通过个性化饮食建议和干预来管理疾病
柳叶刀子刊:人工智能将重塑糖尿病护理的未来
科学控糖,糖尿病患者如何实现精准自我监测?
在医疗领域的应用:亲子鉴定对遗传病防控的意义
在医疗领域的应用:亲子鉴定对遗传病防控的意义
买了机票,还要花钱才能选座?
草莓中毒后的饮食怎样护理
探索新中式风尚:首饰搭配的艺术与技巧
春节宅家观影指南:20部适合全家观看的电影推荐
《唐探1900》与《哪吒之魔童闹海》:传统文化的创新演绎
新华鲜报丨中医药标准化行动计划发布!“中华瑰宝”向未来
全自动智慧中药房自动化设备包含什么
5G技术如何改变农村残疾人生活?
羊角芹鉴别指南:专家教你辨真伪
甘肃祁连山羚羊角鉴别秘籍
一起来了解惠州城——朝京门
一起来了解惠州城——朝京门
云岭山羊:云南的宝藏品种
中国农业大学专家解读:云南山羊养殖如何实现生态平衡
云岭山羊饲养技巧大揭秘
亲子鉴定的合法性有哪些规定
史上最后一位数学全才——庞加莱
五种食物缓解五十岁女性心悸,但不能替代药物治疗
煎中药的正确打开方式,您了解吗?
“蹲个春节搭子”!这届年轻人在线“摇人”
听讲、阅读这些学习方式,其实效率很低,主动学习效果更好