注入依赖关系的正确方法?

时间:2012-02-26 05:53:01

标签: java dependency-injection guice

哪一种是注入依赖项的最佳方式?为什么? 这两者有什么区别?

public abstract class Service {

    private IConfig config;

    @Inject
    public Service(IConfog config) {
        this.config = config
    }
}

或者

public abstract class Service {

    @Inject private IConfig config;

    @Inject
    public Service() {

    }
}

3 个答案:

答案 0 :(得分:4)

构造函数注入(1st)优于setter注入,因为它使得更容易支持“不可变”实体或实体,其行为定义良好且在构造后不可修改。 Constructor vs Setter inject

对我来说,经验法则是首先选择构造函数注入并跳转到setter注入,如果构造函数注入要求我弯腰,即使用“OOP getter and setter”方法处理遗留代码时。

编辑:我假设您正在尝试在“构造函数”和“setter”构造函数之间做出决定。但似乎您正在使用无法实例化的抽象类。也许你还有别的想法吗?

答案 1 :(得分:3)

首先,我没有在抽象类中放入与注入相关的注释 - 在我看来,如果事实上无法实例化,那么决定如何实例化事物是没有意义的(当然这只是我的意见,其他人可能同意与否)。

通常我会按以下方式进行:

public abstract class AbstractService {

  private IConfig config;

  public AbstractService(IConfog config) {
    this.config = config
  }
}

public class Service extends AbstractService {
  @Inject
  public Service(IConfig config) {
    super(config);
  }
}

现在,您可以使用带有和不带依赖注入的两个类(手动构造它,传递所有必需的引用)。此外,您可以确保每次都以适当的状态实例化服务。

答案 2 :(得分:1)

依赖注入的主要目标是通过允许

使单元测试变得容易
Service serviceToTest = new Service(mockConfig);

Service serviceToTest = new Service();
serviceToTest.setConfig(mockConfig);

注入依赖关系的第二种方式使得无法进行abover。您只能通过让Guice创建服务并注入模拟依赖项,或者使用反射来设置模拟依赖项来测试它。