如何在Spring Boot控制器/服务中注入Repository?为何@Autowired遭警告?
Spring Boot @Autowired字段注入相关问题解答
1. 你的注入方式功能上是正确的
这种字段注入的写法能正常工作:Spring会识别UserRepository接口并自动生成代理实现类,将其纳入Spring容器;@Autowired注解会从容器中找到对应的UserRepository实例,注入到Register控制器的userRepository字段中,你的注册接口也能正常完成用户数据的保存。
2. 为什么会出现“Field injection is not recommended”警告?
这个警告源于字段注入存在几个明显弊端:
- 单元测试不便:字段是
private修饰的,没有暴露set方法或构造方法,单元测试时很难手动Mock这个依赖,只能依赖Spring测试上下文启动容器,测试速度慢且灵活性差。 - 依赖关系不透明:从类的外部定义完全看不出它依赖哪些Bean,必须查看类内部字段才能知晓,代码可读性和维护性都很差。
- 存在空指针风险:如果不小心手动实例化这个类(比如
new Register()),userRepository字段会是null,调用方法时直接抛出空指针异常;而构造方法注入可以确保类实例化时依赖就被初始化,从根源避免这类问题。
推荐的注入方式
构造方法注入(最推荐)
Spring 4.3及以上版本,当类只有一个构造方法时,可以省略@Autowired:
@RestController public class Register { private final UserRepository userRepository; public Register(UserRepository userRepository) { this.userRepository = userRepository; } @PostMapping("/register") public User registerUser() { return userRepository.save(new User("test@example.com", "password", true)); } }
Setter注入(次之)
适合处理可选依赖的场景:
@RestController public class Register { private UserRepository userRepository; @Autowired public void setUserRepository(UserRepository userRepository) { this.userRepository = userRepository; } @PostMapping("/register") public User registerUser() { return userRepository.save(new User("test@example.com", "password", true)); } }
内容的提问来源于stack exchange,提问作者Tefly
相关产品推荐
相关产品推荐

