1. @Autowired 字段注入(不推荐)
@Service
public class UserService {@Autowired // 直接在字段上注入private UserRepository userRepository;
}
原理:Spring 启动时扫描所有 @Component、@Service 等注解的类,发现 @Autowired 字段后,自动从容器中查找匹配的 Bean 并注入。
2. Setter 注入(不推荐)
@Service
public class UserService {private UserRepository userRepository;@Autowired // 在 setter 方法上注入public void setUserRepository(UserRepository userRepository) {this.userRepository = userRepository;}
}
原理:Spring 扫描到 @Autowired 标记的 Setter 方法后,自动调用该方法注入依赖。
3. 构造函数注入(推荐)
3.1 手动构造函数
@Service
public class UserService {private final UserRepository userRepository; // final 确保不可变// 手动编写构造函数public UserService(UserRepository userRepository) {this.userRepository = userRepository;}
}
原理:
- Spring 通过反射调用构造函数,自动注入依赖。
- Spring 4.3+ 后,如果类只有一个构造函数,可以省略
@Autowired(Spring 会自动识别)。
3.2 构造函数 + @RequiredArgsConstructor(Lombok)(强烈推荐)
@Service
@RequiredArgsConstructor // Lombok 自动生成构造函数
public class UserService {private final UserRepository userRepository; // final 确保不可变
}
原理:
- Lombok 的
@RequiredArgsConstructor会自动生成一个包含所有final字段和@NonNull字段的构造函数。 - Spring 会自动调用这个构造函数注入依赖(无需
@Autowired)。
总结
| 特性 | @Autowired 字段注入 | Setter 注入 | 构造函数注入 | 构造函数 + @RequiredArgsConstructor |
|---|---|---|---|---|
| 代码简洁性 | ⭐⭐⭐⭐(最简洁) | ⭐⭐⭐ | ⭐⭐(需手动写构造函数) | ⭐⭐⭐⭐(Lombok 自动生成) |
| 可读性 | ⭐(依赖关系隐藏) | ⭐⭐(setter 分散) | ⭐⭐⭐⭐(构造函数明确) | ⭐⭐⭐⭐(和手动构造函数一样清晰) |
| 可测试性 | ❌(难以测试) | ⭐⭐(需手动注入) | ⭐⭐⭐⭐(直接传入 mock) | ⭐⭐⭐⭐(和手动构造函数一样) |
| 不可变性(final) | ❌(不支持) | ❌(不支持) | ⭐⭐⭐⭐(支持) | ⭐⭐⭐⭐(支持) |
| Spring 推荐程度 | ❌(不推荐) | ⭐(仅可选依赖) | ⭐⭐⭐⭐(推荐) | ⭐⭐⭐⭐(推荐) |
| 是否需要 Lombok | ❌ | ❌ | ❌ | ⭐⭐⭐⭐(依赖 Lombok) |