【问题标题】:Placement of @Autowired annotation@Autowired 注解的位置
【发布时间】:2014-04-12 01:38:41
【问题描述】:

我已经看到将 @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
}

我的问题是这两种方法在利弊方面有什么区别。

【问题讨论】:

    标签: java spring spring-mvc annotations pojo


    【解决方案1】:

    我给你的建议是永远不要在字段上使用@Autowired(Spring @Configuration 类除外)。

    原因很简单:测试!!!

    当您在类的字段上使用@Autowired 时,该类变得难以进行单元测试,因为您不能轻易地为被测类使用您自己的(可能是模拟的)依赖项。 当你使用构造函数注入时,类的依赖关系是什么就很明显了,并且创建该类变得很简单(简单的构造函数调用)。

    需要说明的几点:

    1) 有些人可能会争辩说,即使使用了@Autowired,仍然可以使用 Mockito 的 @InjectMocks 或 Spring 的 ReflectionTestUtils.setField 对该类进行单元测试,但我的观点是创建一个被测单元应该尽可能简单。

    2) 可以提到的另一点是,构造函数中可能有许多参数,使得手动调用构造函数(在测试中或其他地方)变得困难。然而,这不是关于创建类的问题,而是设计中的问题。当一个类有很多依赖项时,大多数情况下它会尝试做too much 并且需要分解成具有较少依赖项的更小的类。

    【讨论】:

    • 在这些 cmets 上同上 - 自动装配应该只出现在 @Configuration 注释类中!
    【解决方案2】:

    @Autowired setter 方法上的注解 是去掉 XML 配置文件中的元素。当 Spring 找到与 setter 方法一起使用的 @Autowired 注解时,它会尝试对该方法执行 byType 自动装配

    @Autowired属性注解是为了摆脱setter方法。当您使用 Spring 传递自动装配属性的值时,将自动为这些属性分配传递的值或引用。

    以下是这两种用法的示例:

    http://www.tutorialspoint.com/spring/spring_autowired_annotation.htm

    【讨论】:

    • 为了可测试性,我建议不要将 Autowired injection by field 设置为“private”。您不能使用 JUnit 设置该值。要么使用基于构造函数的注入,要么使用 Autowired 的默认范围字段注入。
    【解决方案3】:

    Springsource blog post 提到构造函数注入可以很容易地验证所需的依赖关系,如果与构造函数断言结合使用,无论如何都是良好的做法,并且如果类在 Spring 之外使用 new 运算符实例化也可以工作:

    @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 或属性注入,还有用于验证缺失依赖项的 @Required 注释或 @Autowired(required = true)。根据博客文章,构造函数注入提供了这个优势,但由于历史原因,在 Spring 中更频繁地使用 setter 注入。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-06-27
      • 1970-01-01
      • 2018-03-24
      • 1970-01-01
      • 2014-10-25
      • 1970-01-01
      • 2011-04-01
      相关资源
      最近更新 更多