为什么不推荐使用@Autowired进行依赖注入
相信很多人在写SpringBoot项目时,不管是在注入bean对象时,都经常使用@Autowired
注解进行依赖注入,我们也认为他是非常方便的注入方式,只需要在类中需要注入的对象上加上这么一个注解,在运行时他的实例对象就会轻轻松松注入进来,比如在controller层中注入service层的对象:
@RestController
@RequestMapping("/admin/employee")
@Api(tags = "员工相关接口")
@Slf4j
public class EmployeeController {
@Autowired //注入业务层对象
private EmployeeService employeeService;
@Autowired //注入jwt配置类对象
private JwtProperties jwtProperties;
//相关接口的编写...
}
但是当我们把鼠标放到@Autowired注解上时,spring会提示我们不建议使用这种注入方式:
那么究竟是怎么一回事呢,
虽然@Autowired
注解是一种方便的依赖注入方式,但是它具有一些缺点,导致在某些情况下不推荐使用:
- 紧耦合性增加: 使用@Autowired注解时,类与Spring框架紧密耦合在一起,这会降低类的可移植性和可测试性。如果类中存在大量的@Autowired注解,那么类的实例化和测试可能会变得更加困难。
- 难以排查问题: 在使用@Autowired注解时,Spring框架会自动完成依赖注入,但是如果注入失败或者注入的bean不符合预期,很难通过编译器或者IDE进行发现和排查问题。
- 不够清晰: 使用@Autowired注解时,注入的依赖关系可能并不清晰,特别是当一个类中存在多个@Autowired注解时,很难确定哪些依赖是必须的、哪些是可选的。
所以说spring是并不希望我们使用这种注入方式,那么我们该用什么注入方式呢,你只需要点击@Autowired,并按下ALT+回车,就会看到它可以帮我们改造为另一种注入方式:
没错就是通过构造方法:
private final EmployeeService employeeService;
private final JwtProperties jwtProperties;
//构造方法
public EmployeeController(EmployeeService employeeService, JwtProperties jwtProperties) {
//注入业务层对象
this.employeeService = employeeService;
//注入jwt配置类对象
this.jwtProperties = jwtProperties;
}
在项目启动时,Spring容器自动构建Controller时,如果发现Controller的构造函数需要一个EmployeeService类型的参数,它会在Spring容器中寻找已经注册的EmployeeService bean,并将其注入到构造函数中。这就是Spring的依赖注入机制的工作方式之一。
但是,与此同时我们又遇到了一个问题,如果在当前类中需要的bean对象十分庞大,难道我们要在构造方法中一个一个写出来吗,不仅麻烦,看起来也是黑黑的一坨,这时候,我们又可以对代码进行改造,我们可以使用lombok提供的@RequiredArgsConstructor
注解,我们就不必再手写构造函数了:
@RequiredArgsConstructor
public class EmployeeController {
//业务层对象
private final EmployeeService employeeService;
//jwt配置类对象
private final JwtProperties jwtProperties
//相关接口的编写...
}
它会为类的final字段生成一个构造函数,并将这些字段作为参数传入构造函数中。