Spring 中的 DI(Dependency Injection,依赖注入)是 Spring 框架的核心特性之一,也是控制反转(IoC,Inversion of Control)原则的具体实现。

什么是 DI?

依赖注入是一种设计模式,它将对象的依赖关系从对象内部移到外部容器(Spring 容器)来管理。简单来说,就是由容器负责创建对象并注入它所依赖的其他对象,而不是由对象自己创建或查找依赖。

DI 的核心概念

1. 依赖关系

// 没有 DI 的情况
public class UserService {
    private UserDao userDao;
    
    public UserService() {
        // 对象自己创建依赖,耦合度高
        this.userDao = new UserDao();
    }
}

// 使用 DI 的情况
public class UserService {
    private UserDao userDao;
    
    // 通过构造函数注入依赖
    public UserService(UserDao userDao) {
        this.userDao = userDao;
    }
}

2. 控制反转

  • 传统方式:对象自己控制依赖的创建和管理
  • DI 方式:控制权反转给 Spring 容器,由容器负责注入依赖

DI 的三种注入方式

1. 构造函数注入(推荐)

@Component
public class UserService {
    private final UserDao userDao;
    
    @Autowired
    public UserService(UserDao userDao) {
        this.userDao = userDao;
    }
}

2. Setter 方法注入

@Component
public class UserService {
    private UserDao userDao;
    
    @Autowired
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
}

3. 字段注入(不推荐)

@Component
public class UserService {
    @Autowired
    private UserDao userDao;
}

DI 的优势

  1. 降低耦合度:对象之间通过接口交互,不直接依赖具体实现
  2. 提高可测试性:可以轻松注入 Mock 对象进行单元测试
  3. 便于维护:依赖关系集中管理,修改配置即可改变实现
  4. 促进代码复用:组件可以灵活组合使用
  5. 符合单一职责原则:对象专注于自己的业务逻辑

Spring 中 DI 的实现

Spring 通过以下注解实现 DI:

  • @Component:标记类为 Spring 管理的 Bean
  • @Autowired:自动装配依赖
  • @Service@Repository@Controller:特定场景的组件注解
  • @Qualifier:指定注入的 Bean 名称
  • @Value:注入配置值

实际示例

// 定义接口
public interface MessageService {
    String sendMessage(String message);
}

// 实现类
@Service("emailService")
public class EmailService implements MessageService {
    public String sendMessage(String message) {
        return "Email: " + message;
    }
}

@Service("smsService")
public class SmsService implements MessageService {
    public String sendMessage(String message) {
        return "SMS: " + message;
    }
}

// 使用依赖注入
@Service
public class NotificationService {
    private final MessageService messageService;
    
    @Autowired
    public NotificationService(@Qualifier("emailService") MessageService messageService) {
        this.messageService = messageService;
    }
    
    public void sendNotification(String message) {
        System.out.println(messageService.sendMessage(message));
    }
}

总结

DI 是 Spring 框架的基石,它通过将对象的创建和依赖管理交给容器,实现了松耦合、易测试、易维护的代码结构。在现代 Java 开发中,DI 已经成为主流的设计模式,不仅限于 Spring,在其他框架中也有广泛应用。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐