假设我们对一个类中的各个字段使用@Autowired
注解,并且我们没有编写也可以设置字段的setter或构造函数。
问题-访问修饰符应该是什么,private
还是package-private
(即无)?
例如:
public class MyClass {
@Autowired
private MyService myService;
}
vs
public class MyClass {
@Autowired
MyService myService;
}
在第一种情况下(private
fields),Spring使用反射来连接字段,即使它没有setter。
第二种情况(package-private
字段)允许我们访问这些字段(例如,设置模拟),如果我们需要扩展类以进行测试的话。
所以这两种情况都很好,但哪种更值得推荐,特别是在测试方面?
5条答案
按热度按时间7gyucuyw1#
所以这两种情况都很好,但哪种更值得推荐,特别是在测试方面?
我认为属性应该是
private
:因为使用getter方法来提供对属性的访问总是很好的,而不是允许其他类直接访问它们。
出于测试目的,
private properties
的mocks
注入将与package-private
属性的注入以相同的方式工作。例如,使用
Mockito
,您可以将private MyService
的模拟注入MyClass
,如下所示:dsekswqp2#
我通常更喜欢私有字段和使用setter注入:
允许服务被@Autowired,但是设置一个模拟的示例用于单元测试。
jhiyze9q3#
第一种情况还允许您根据框架注入模拟。例如使用Mockito的
@InjectMocks
注解。你在Spring测试中也有ReflectionTestUtils.setField
,...我个人不太喜欢为了测试目的而过多地修改类,所以我会选择第一种情况。但最终,这主要取决于您首选的测试框架。
gmxoilav4#
我通常不会使用@Autowired作为私有字段或方法。@Autowired意味着,来自外部的某个人将设置此字段。另一方面,“私有”意味着除了这个类之外,没有人可以使用它。
如果JIT编译器以某种方式优化了这段代码,那么混合使用@Autowired和private理论上会导致问题。它可能是一个Java内存模型并发相关的问题,这将是生产,不可能重现。
我会使自动布线字段至少包可见。作为免费的奖励,它将允许编写没有技巧和变通方法的单元测试。
**UPDATE:**另外,我会将这些字段声明为
volatile
,以避免与Java内存模型相关的可见性冲突。Spring开发人员使用了一些技巧来使autowired字段在没有显式同步访问的情况下工作,但我不确定这些技巧是否能在任何硬件上的任何JVM中顺利工作。lndjwyie5#
我宁愿在@Autowired字段上使用private,原因如下: