别再懵圈了!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。 记住,多写代码,多实践,才能真正掌握它们!

相关推荐
KK溜了溜了1 小时前
JAVA-springboot log日志
java·spring boot·logback
我命由我123452 小时前
Spring Boot 项目集成 Redis 问题:RedisTemplate 多余空格问题
java·开发语言·spring boot·redis·后端·java-ee·intellij-idea
面朝大海,春不暖,花不开2 小时前
Spring Boot消息系统开发指南
java·spring boot·后端
hshpy2 小时前
setting up Activiti BPMN Workflow Engine with Spring Boot
数据库·spring boot·后端
jay神2 小时前
基于Springboot的宠物领养系统
java·spring boot·后端·宠物·软件设计与开发
不知几秋3 小时前
Spring Boot
java·前端·spring boot
howard20054 小时前
5.4.2 Spring Boot整合Redis
spring boot·整合redis
TracyCoder1234 小时前
接口限频算法:漏桶算法、令牌桶算法、滑动窗口算法
spring boot·spring·限流
饮长安千年月4 小时前
JavaSec-SpringBoot框架
java·spring boot·后端·计算机网络·安全·web安全·网络安全
考虑考虑5 小时前
Jpa中的@ManyToMany实现增删
spring boot·后端·spring