我已经看到@Autowired注释放在用作控制器的POJO的构造函数之前。
@Controller
public class LoginController{
private UsuarioService usuarioService;
@Autowired
public void LoginController(UsuarioService usuarioService){
this.usuarioService = usuarioService;
}
// More code
}
这个构造函数将对我们希望Spring注入的对象的引用作为参数。但是,如果我在属性声明之前放置此注释,则应用程序的工作方式相同。
@Controller
public class LoginController{
@Autowired
private UsuarioService usuarioService;
// More code
}
我的问题是这两种方法在利弊方面有何不同。
答案 0 :(得分:2)
我的建议是永远不要在字段上使用@Autowired
(Spring @Configuration类除外)。
原因很简单:测试!!!!
当您在类的字段上使用@Autowired
时,该类变得难以进行单元测试,因为您无法轻松地将自己的(可能模拟的)依赖项用于被测试的类。
当你使用构造函数注入时,会立即明白类的依赖性是什么,并且创建该类变得直接(简单的构造函数调用)。
需要提出的一些观点:
1)有些人可能会争辩说,即使使用@Autowired
,仍然可以使用Mockito的@InjectMocks
或Spring {{1}进行单元测试。但我的意见是,被测单元的创建应该尽可能简单。
2)可以提到的另一点是,构造函数中可能有许多参数使得构造函数的手动调用(在测试或其他地方)很困难。然而,这不是关于类的创建的问题,而是设计中的问题。当一个类需要很多依赖项时,在大多数情况下它会尝试too much并且需要分解为具有较少依赖项的较小类。
答案 1 :(得分:0)
@Autowired
注释是摆脱XML配置文件中的元素。当Spring找到与setter方法一起使用的@Autowired注释时,它会尝试在方法上执行byType自动装配
@Autowired
关于属性的注释是摆脱setter方法。当您使用Spring传递自动装配属性的值时,将自动为这些属性分配传递的值或引用。
以下是两种用法的示例:
http://www.tutorialspoint.com/spring/spring_autowired_annotation.htm
答案 2 :(得分:0)
这个Springsource blog post提到构造函数注入可以很容易地验证所需的依赖项,如果结合使用的构造函数断言仍然是良好的实践,并且如果使用new运算符在Spring外部实例化类,它也可以工作: / p>
@Controller
public class LoginController{
private UsuarioService usuarioService;
@Autowired
public void LoginController(UsuarioService usuarioService){
if (usuarioService == null) {
throw new IllegalArgumentException("usuarioService cannot be null.");
}
this.usuarioService = usuarioService;
}
}
这种类型的断言是一般的最佳实践,建议独立于类是否为Spring bean。
对于setter或property注入,还有@Required
注释用于验证缺少的依赖项或@Autowired(required = true)
。根据博客文章,构造函数注入提供了这种优势,但由于历史原因,在Spring中更频繁地使用setter注入。