3

假设我们有以下代码:

public interface Rock {
    // Minerals are a concrete class; omitted for brevity
    public Minerals getMinerals();
}

public class Granite implements Rock {
    // @Inject #1 - field
    private Minerals minerals;

    // @Inject #2 - constructor
    public Granite(Minerals mins) {
        super();
        setMinerals(mins);
    }

    public Minerals getMinerals() {
        return minerals;
    }

    // @Inject #3 - setter
    public void setMinerals(Minerals mins) {
        minerals = mins
    }
}

public class RockModule extends AbstractModule {
    public void configure(Binder guiceBinder) {
        Minerals m = new Minerals(true, 3, MineralEnum.Sedimentary);

        guiceBinder.bind(Minerals.class).toInstance(m);
        guiceBinder.bind(Rock.class).to(Granite.class);
    }
}

public class TestInjections {
    public static void main(String[] args) {
        RockModule mod = new RockModule();
        Injector injector = Guice.createInjector(mod);

        Granite gran = injector.getInstance(Granite.class);
    }
}

我已经注释掉了 3 个@Inject注释,因为它们是这里的变量——我想知道 Guice 在所有 3 种情况下(字段级、构造函数级或设置器级注入)的行为方式。

  • Granite实例是否总是注入Minerals模块中配置的实例?注入类型(三种中的每一种)如何影响Granite注入器返回的实例 - 还是它们都相同?
  • 如果我根本没有Minerals在模块中显式绑定并且 Minerals没有定义公共的无参数构造函数怎么办?对于所有三种注入场景,Guice 如何实例化Minerals要为请求Granite对象返回的实例?
4

1 回答 1

3
  1. Minerals无论您选择哪种注入技术,都将始终注入到 中Granite,但有些注入比其他注入“更干净” - 例如,选项 1 使您对注入的完成方式的控制较少,选项 3 意味着您的课程不能不可变的。
  2. 如果Minerals未绑定、缺少公共无参数构造函数并且缺少@Inject构造函数,则 Guice 会引发异常,除非您使用@Inject(optional = true).
于 2012-04-12T17:44:31.827 回答