当前位置: 首页 > 知识库问答 >
问题:

Spring依赖注入 - 私有字段 - 反模式?为什么它甚至有效?

卫振
2023-03-14

我通常是一名c#开发人员,但是现在在Java上工作,我偶尔会看到很多在私有属性上使用Spring的依赖注入,没有设置值的公共方法。我很惊讶这真的有用,但我想通过思考这是可能的?

这肯定是很糟糕的做法吧?!我看不出任何对类进行单元测试或检查的人怎么可能知道私有成员需要从某个外部框架中设置。

当您进行单元测试时,您将如何设置属性?或者只是单独使用类?

我想你必须在你的单元测试中使用spring,这看起来有点过头了。当然,没有IOC容器,你也可以进行单元测试。这个类变得完全依赖于spring...

我错过了什么吗?

依赖注入不应该总是涉及某种类型的公共setter,如果可能的话最好使用构造函数吗?或者我缺少Java的一些东西吗。。。?

谢谢

共有3个答案

夏侯旻
2023-03-14

有基于字段的注入、基于setter的注入、基于注释的注入和基于构造函数的注入。基于构造函数的注入最适合测试,因为您可以轻松模拟所需的依赖关系。尽可能使用最终字段定义服务总是很好的。

class MyService {

    private final MyDependency dependency;

    @Autowired // not needed, explicit just for this example
    public MyService(MyDependency dependency) {
        this.dependency = dependency;
    }

}
戚星腾
2023-03-14

是的,它有效。一些测试框架允许注入私有字段。

是的,它是反模式的,增加了技术负担——容易编写,但很难维护这样的代码,而不是编译时错误,你会有运行时错误。不要那样做。使用构造函数注入。

施季
2023-03-14

即使您有私有字段,也可以随时模仿注入的beans。您应该看看Spring文档中的< code>@MockBean。本质上,您可以执行以下操作:

@ExtendWith({SpringExtension.class})
class MyServiceTest{

    @MockBean
    private RepositoryInterface repository;

    @Autowired
    private MyService service;

}

假设RepositoryInterface是注入MyService中的接口(而不是具体类)。如果您创建了pom,那么JUnit5的SpringExtension应该已经在您的依赖项中了。来自SpringInitialzr的xml将使用另一个名为Mockito的框架为该接口构建一个mock(也许可以看看)。然后,Spring IoC将在服务中注入创建的mock。这适用于现场注入:

@Service
public class MyService{

    @Autowired
    private RepositoryInterface repositoryInterface
}

setter注入:

@Service
public class MyService{

    private RepositoryInterface repositoryInterface

    @Autowired
    public void setRepository(RepositoryInterface repositoryInterface){
        this.repositoryInterface = repositoryInterface;
    }
}

或构造函数注入:

@Service
public class MyService{

    private RepositoryInterface repositoryInterface

    public MyService(RepositoryInterface repositoryInterface){
        this.repositoryInterface = repositoryInterface;
    }
}

本质上,最后一个是推荐的,因为这样您的服务的依赖项将是显式的。它更多的是代码风格。不推荐字段注入,因为iy隐藏了您的类依赖项。因此,使用构造函数注入构建测试的推荐方法如下:

@ExtendWith({SpringExtension.class})
class MyServiceTest{

    @MockBean
    private RepositoryInterface repository;

    private MyService service;

    @BeforeEach
    void setup(){
        service = new MyService(repository);
    }
}

希望这有助于您的理解。

 类似资料:
  • 问题内容: 已经发布了几个问题,其中包括有关依赖项注入的特定问题,例如何时使用它以及支持它的框架。然而, 什么是依赖项注入?何时/为什么/不应该使用它? 问题答案: 依赖注入 将依赖传递给其他 对象 或 框架 (依赖注入器)。 依赖注入使测试更加容易。注入可以通过 构造函数 完成。 其构造函数如下: 问题 :如果涉及复杂的任务,例如磁盘访问或网络访问,则 很难 对其进行单元测试。程序员必须进行模拟

  • 本文向大家介绍.NET IoC模式依赖反转(DIP)、控制反转(Ioc)、依赖注入(DI),包括了.NET IoC模式依赖反转(DIP)、控制反转(Ioc)、依赖注入(DI)的使用技巧和注意事项,需要的朋友参考一下 依赖倒置原则(DIP) 依赖倒置(Dependency Inversion Principle,缩写DIP)是面向对象六大基本原则之一。他是指一种特定的的解耦形式,使得高层次的模块不依

  • 我不太明白它解决了什么问题。它看起来像是这样说:“Hi.当你运行到这个函数时,返回一个对象,它是这种类型的,并且使用这些参数/数据。” 但是...我为什么要用这个?注我也从来不需要使用,但我理解这是为了什么。 在构建一个网站或桌面应用程序时,有哪些实际情况可以使用DI?我可以很容易地想出为什么有人想在游戏中使用接口/虚拟函数的例子,但是在非游戏代码中使用这种方法是极其罕见的(非常罕见,以至于我都记

  • 问题内容: 给出以下代码: 以 主要 方式完成的组件连接是否正确,将依赖关系连接在一起?看来我在代码中有点用完了。有没有比这更好的通用模式了?还是我想得太多? 问题答案: 是的,facebookgo注入库允许您接受注入的成员,并将为您连接图表。 代码:https://github.com/facebookgo/inject 文档:https : //godoc.org/github.com/fac

  • 问题内容: 谁能帮我 .. ?我试图用JAX-RS创建一个Web服务,但是它给了我这个例外: org.glassfish.jersey.server.wadl.internal.WadlResource.wadlContext 这是我的java类的代码: -– Web.xml部分: -—使用的罐子是: javax.annotation-api-1.2.jar javax.ws.rs-api-2.0

  • 问题内容: 对于Java,依赖注入作为纯OOP工作,即,您提供要实现的接口,并且在框架代码中接受实现已定义接口的类的实例。 现在,对于Python,您可以以相同的方式进行操作,但是对于Python,我认为该方法的开销太大。那么,您将如何以Pythonic的方式实现它呢? 用例 说这是框架代码: 基本方法 最幼稚(也许是最好的?)方法是要求将外部函数提供给构造函数,然后从该方法中调用它。 框架代码: