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

如何解决Spring依赖注入-私有字段-反模式?为什么它甚至起作用?

我通常是c#开发人员,但是现在正在使用Java,然后我看到在 private 属性上使用Spring进行了很多依赖注入,没有公开设置值的方法。我很惊讶这确实有效,但是我想可以通过反思吗?

这肯定是可怕的做法吗?!我看不到任何单元测试或检查类的人怎么可能知道需要从某个外部框架设置私有成员。

在进行单元测试时,您甚至将如何设置属性?还是只是单独使用课程?

我想您必须在单元测试中使用spring,这似乎实在是太过分了。当然,您无需IOC容器就可以进行单元测试?该类完全依赖于spring ...

在这里错过了什么吗?

依赖注入是否不总是涉及某种公共的setter,并且在可能的情况下最好使用构造函数?还是我想念的关于Java的东西??

谢谢

解决方法

即使您有私有字段,也可以始终模拟注入的bean。您应该查看Spring文档中的@MockBean。本质上,您可以执行以下操作:

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

    @MockBean
    private RepositoryInterface repository;

    @Autowired
    private MyService service;

}

假设RepositoryInterface是在MyService中注入的接口(而不是具体的类)。发生的事情是,如果您是从Spring Initialzr创建pom.xml的,那么JUnit5的SpringExtension应该已经存在于您的依赖项中,它将使用另一个称为Mockito的框架为该接口构建一个模拟文件(也许看看对此)。然后,Spring IoC将在服务中注入创建的模拟。这适用于现场注入:

@Service
public class MyService{

    @Autowired
    private RepositoryInterface repositoryInterface
}

固定注入:

@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;
    }
}

基本上,最后一个是推荐的,因为这样,您的服务的依赖关系将是显式的。更多有关代码样式的信息。不建议使用字段注入,因为它会隐藏您的类依赖项。因此,建议使用构造函数注入来构建测试的方法如下:

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

    @MockBean
    private RepositoryInterface repository;

    private MyService service;

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

希望这有助于您理解。

,

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

class MyService {

    private final MyDependency dependency;

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

}
,

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

是的,它是反模式,增加了技术负担-易于编写,但难以维护此类代码,而不是编译时错误,您将遇到运行时错误。不要那样做使用构造函数注入。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?