依赖注入是通过外部传入依赖对象来解耦类间关系,提升可维护性和可测试性。它将对象创建与使用分离,由容器或调用者注入依赖,避免类内部直接new对象。Java中常见实现方式有构造函数注入、Setter方法注入和字段注入,其中构造函数注入最推荐,能保证依赖不可变且不为空。例如UserService通过构造函数接收UserRepository实例,而非自行创建,实现控制反转(IoC)。Spring框架通过@Component、@Service和@Autowired等注解自动扫描并装配Bean,简化依赖管理。开发者也可手动实现简易DI容器,利用工厂模式和注册表存储对象实例,适用于小型项目或学习场景。核心目标是降低耦合,使代码更灵活、易于测试和维护。

在Java中实现对象之间的依赖注入,核心是解耦对象创建与使用,提升代码的可维护性和可测试性。依赖注入(Dependency Injection, DI)是面向对象编程中管理对象依赖关系的一种有效方式。它让一个类不需要自己创建所依赖的对象,而是通过外部传入,从而降低耦合度。
什么是依赖注入
当一个类A需要使用另一个类B的实例来完成某些功能时,类A就依赖于类B。传统做法是在类A内部直接new一个类B的实例,这种方式导致类A和类B高度耦合。依赖注入则是将类B的实例从外部传递给类A,由外部容器或调用者负责管理依赖关系。
例如:
public class UserService {private UserRepository userRepository;
// 通过构造函数注入依赖
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public void saveUser(String name) {
userRepository.save(name);
}
}
这里UserService不负责创建UserRepository,而是由外部传入,实现了控制反转(IoC)。
立即学习“Java免费学习笔记(深入)”;
三种常见的注入方式
Java中依赖注入主要有以下三种实现方式:
- 构造函数注入:在构造对象时传入依赖。这是最推荐的方式,能保证依赖不可变且不为空。
- Setter方法注入:提供set方法,允许外部设置依赖。适合可选依赖或运行时更改依赖的场景。
- 字段注入(反射):通过注解直接注入到私有字段,常见于Spring框架。虽然写法简洁,但不利于单元测试和显式依赖管理。
示例:Setter注入
public class UserService {private UserRepository userRepository;
public void setUserRepository(UserRepository userRepository) {
this.userRepository = userRepository;
}
}
使用框架简化依赖管理
手动管理大量对象的依赖会变得复杂,因此常用框架来自动处理。Spring Framework是最流行的Java依赖注入解决方案。
通过@Component、@Service、@Autowired等注解,Spring可以自动扫描并装配Bean:
@Servicepublic class UserService {
@Autowired
private UserRepository userRepository;
}
或者使用构造函数注入(更推荐):
@Servicepublic class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
}
Spring Boot中启用组件扫描后,容器会自动创建和注入这些对象实例。
手动实现简易依赖容器
如果不使用框架,也可以通过工厂模式+注册表实现简单的DI容器:
public class SimpleContainer {private Map
public
instances.put(type, instance);
}
public
return (T) instances.get(type);
}
}
使用方式:
var container = new SimpleContainer();container.register(UserRepository.class, new UserRepository());
container.register(UserService.class, new UserService(container.get(UserRepository.class)));
这种轻量级方式适用于小型项目或学习理解DI原理。
基本上就这些。依赖注入的关键在于把对象的创建和使用分离,无论是通过Spring这样的框架,还是手动管理,目标都是让代码更灵活、更容易测试和维护。










