别再懵圈了!Spring IOC/DI,看完不懂你喷我!

一、什么是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. 简单示例:

java 复制代码
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 ,UserServiceUserDao 是组件,需要被 Spring 管理。
    • @Autowired: 告诉 Spring ,UserService 需要一个 UserDao 对象。 Spring 会自动创建一个 UserDao 对象,并把它"注入"到 UserService 中。
    • 你不需要自己 new UserDao(),Spring 帮你做了。

2. 使用配置文件注入:

java 复制代码
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:
properties 复制代码
app.name=My Awesome App
  • 解释:
    • @Value: 告诉 Spring,从 application.properties 文件中读取 app.name 的值,并把它"注入"到 appName 变量中。
    • 你不需要自己读取配置文件,Spring 帮你做了。

3. 使用构造器注入:

java 复制代码
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. 使用接口和多态:

java 复制代码
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 是一个接口,EmailServiceSMSService 是它的实现类。
    • @Qualifier: 告诉 Spring,要注入哪个 MessageService 的实现类。
    • 这种方式可以让你更容易切换不同的消息服务,而不用修改 NotificationService 的代码。

5. 更复杂的场景:

  • AOP (面向切面编程): 使用 IOC 和 DI 来管理切面,实现日志记录、权限控制等功能。
  • 事务管理: 使用 IOC 和 DI 来管理事务,保证数据的一致性。
  • 集成其他框架: 使用 IOC 和 DI 来集成 MyBatis、Hibernate 等框架。

六、总结

  • IOC: 就像你把盖房子的事情交给建筑公司,你不用自己管材料和工人了,Spring帮你管🏢。
  • DI: 就像建筑公司把砖头、水泥自动送到房子里,你不用自己去搬了,Spring帮你送🚚。
  • 好处: 代码更清晰、更容易修改、更容易测试,你更省心!😊

希望这篇文章能够帮助你理解 Spring中的 IOC 和 DI。 记住,多写代码,多实践,才能真正掌握它们!

相关推荐
武昌库里写JAVA41 分钟前
39.剖析无处不在的数据结构
java·vue.js·spring boot·课程设计·宠物管理
李白的粉6 小时前
基于springboot的在线教育系统
java·spring boot·毕业设计·课程设计·在线教育系统·源代码
小马爱打代码7 小时前
SpringBoot原生实现分布式MapReduce计算
spring boot·分布式·mapreduce
iuyou️7 小时前
Spring Boot知识点详解
java·spring boot·后端
一弓虽7 小时前
SpringBoot 学习
java·spring boot·后端·学习
来自星星的猫教授9 小时前
spring,spring boot, spring cloud三者区别
spring boot·spring·spring cloud
乌夷10 小时前
使用spring boot vue 上传mp4转码为dash并播放
vue.js·spring boot·dash
A阳俊yi12 小时前
Spring Boot日志配置
java·spring boot·后端
苹果酱056712 小时前
2020-06-23 暑期学习日更计划(机器学习入门之路(资源汇总)+概率论)
java·vue.js·spring boot·mysql·课程设计
斜月12 小时前
一个服务预约系统该如何设计?
spring boot·后端