属性与构造函数上的 Spring @Autowire

新手上路,请多包涵

因此,由于我一直在使用 Spring,如果我要编写一个具有依赖项的服务,我将执行以下操作:

 @Component
public class SomeService {
     @Autowired private SomeOtherService someOtherService;
}

我现在遇到了使用另一个约定来实现相同目标的代码

@Component
public class SomeService {
    private final SomeOtherService someOtherService;

    @Autowired
    public SomeService(SomeOtherService someOtherService){
        this.someOtherService = someOtherService;
    }
}

这两种方法都会起作用,我明白这一点。但是使用选项 B 有什么好处吗?对我来说,它在类和单元测试中创建了更多代码。 (必须编写构造函数并且不能使用@InjectMocks)

有什么我想念的吗?除了向单元测试添加代码之外,自动装配的构造函数还有什么作用吗?这是进行依赖注入的更优选方法吗?

原文由 GSUgambit 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 441
2 个回答

是的,选项 B(称为构造函数注入)实际上比字段注入更推荐,它有几个优点:

  • 依赖关系被清楚地识别出来。在测试时没有办法忘记一个,或者在任何其他情况下实例化对象(比如在配置类中显式创建 bean 实例)
  • 依赖关系可以是最终的,这有助于稳健性和线程安全
  • 您不需要反射来设置依赖项。 InjectMocks 仍然可用,但不是必需的。您可以自己创建模拟并通过简单地调用构造函数来注入它们

有关更详细的文章,请参阅 这篇博客 文章,作者是 Spring 贡献者之一 Olivier Gierke

原文由 JB Nizet 发布,翻译遵循 CC BY-SA 3.0 许可协议

我将用简单的话向您解释:

在选项 (A) 中, 您允许任何人(在 Spring 容器外部/内部的不同类中)使用默认构造函数(如 new SomeService() )创建实例,这并不像您需要的那样好 SomeOtherService 对象(作为依赖项)为您的 SomeService

除了向单元测试添加代码之外,自动装配的构造函数还有什么作用吗?这是进行依赖注入的更优选方法吗?

选项 (B) 是首选方法,因为它不允许在不实际解析 SomeOtherService 依赖项的情况下创建 SomeService 对象。

原文由 developer 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题