Spring @Autowired字段-哪个访问修饰符,private还是package-private?

bxgwgixi  于 2023-05-21  发布在  Spring
关注(0)|答案(5)|浏览(272)

假设我们对一个类中的各个字段使用@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字段)允许我们访问这些字段(例如,设置模拟),如果我们需要扩展类以进行测试的话。
所以这两种情况都很好,但哪种更值得推荐,特别是在测试方面?

7gyucuyw

7gyucuyw1#

所以这两种情况都很好,但哪种更值得推荐,特别是在测试方面?
我认为属性应该是private

@Autowired
private MyService myService;

因为使用getter方法来提供对属性的访问总是很好的,而不是允许其他类直接访问它们。
出于测试目的,private propertiesmocks注入将与package-private属性的注入以相同的方式工作。
例如,使用Mockito,您可以将private MyService的模拟注入MyClass,如下所示:

public class MyClassTest {
    @Mock
    MyService service;
    
    @InjectMocks
    MyClass serv = new MyClass();
    
    @Before
    public void init() {
        MockitoAnnotations.initMocks(this);
    }
}
dsekswqp

dsekswqp2#

我通常更喜欢私有字段和使用setter注入:

public class MyClass {

    private MyService myService;

    @Autowired
    public void setMyService(MyService myService) {
        this.myService = myService;
    }
}

允许服务被@Autowired,但是设置一个模拟的示例用于单元测试。

jhiyze9q

jhiyze9q3#

第一种情况还允许您根据框架注入模拟。例如使用Mockito的@InjectMocks注解。你在Spring测试中也有ReflectionTestUtils.setField,...
我个人不太喜欢为了测试目的而过多地修改类,所以我会选择第一种情况。但最终,这主要取决于您首选的测试框架。

gmxoilav

gmxoilav4#

我通常不会使用@Autowired作为私有字段或方法。@Autowired意味着,来自外部的某个人将设置此字段。另一方面,“私有”意味着除了这个类之外,没有人可以使用它。
如果JIT编译器以某种方式优化了这段代码,那么混合使用@Autowired和private理论上会导致问题。它可能是一个Java内存模型并发相关的问题,这将是生产,不可能重现。
我会使自动布线字段至少包可见。作为免费的奖励,它将允许编写没有技巧和变通方法的单元测试。

**UPDATE:**另外,我会将这些字段声明为volatile,以避免与Java内存模型相关的可见性冲突。Spring开发人员使用了一些技巧来使autowired字段在没有显式同步访问的情况下工作,但我不确定这些技巧是否能在任何硬件上的任何JVM中顺利工作。

lndjwyie

lndjwyie5#

我宁愿在@Autowired字段上使用private,原因如下:

  • 我使用这些字段进行依赖注入,通常在服务类中,以使用其他服务类。在这种情况下,我希望将这些字段保留到当前类。
  • 此外,扩展这个类可能会导致不同的逻辑,所以可能需要另一个@Autowired字段的实现,因此使用private而不是package-private。
  • 此外,在重构时,它有助于查看何时不再使用这样的字段,因为包私有字段在未使用时不会显示警告(假设您的IDE是Eclipse -实际上我不知道其他IDE)。

相关问题