注入私人,包装或公共领域或提供制定者?

dea*_*mon 15 java scope dependency-injection

我看到许多Java示例使用依赖注入私有字段而没有像这样的公共setter:

public SomeClass {
  @Inject
  private SomeResource resource;
}
Run Code Online (Sandbox Code Playgroud)

但是,当应该手动执行注射时,例如在单元测试中,这是一个坏主意.

有几种可能性来解决这个问题:

  • 添加公共setter: setSomeResource(SomeResource r)
  • 让这个领域公开
  • 使字段包受到保护

我想避开二传手,因为它没有真正发生.所以我更喜欢公共或包裹保护.您有什么推荐的吗?

And*_*ues 15

避免为字段创建setter的一种方法是使用构造函数注入.这甚至允许您将该字段声明为final.

它是这样的:

public class SomeClass {
    private final SomeResource resource;

    @Inject
    public SomeClass(SomeResource resource) {
        this.resource = resource;
    }
}
Run Code Online (Sandbox Code Playgroud)


Adr*_*ter 8

添加setter不是最佳解决方案,因为您要添加不需要的生产代码.

另一种方法是使用Spring的ReflectionTestUtils类使用反射注入测试依赖项,请参阅http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/test/util/ReflectionTestUtils.html

EDIT(2017):但是,反射是比添加setter更糟糕的解决方案.造成这种混乱的原因是Spring可以在没有setter或构造函数的情况下注入值.我目前的立场是坚持使用其中任何一种,并避免使用黑魔法注射做法.


Era*_*dan 7

我更喜欢二传手

  • 它更容易调试(在setter中放置断点而不是字段访问/修改)
  • 更容易记录
  • 更容易添加一些验证(虽然这并不总是最好的地方)
  • 更容易支持双向维护(尽管IOC容器可以处理)
  • 任何其他"手动AOP"的目的

但那只是我的个人意见

  • 会使对象可变,这可能是一个问题 (5认同)