当注射类型改变时,Guice的行为方式不同

时间:2012-04-12 17:37:40

标签: java dependency-injection guice

假设我们有以下代码:

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实例?

1 个答案:

答案 0 :(得分:3)

  1. Minerals将始终注入Granite,无论您选择哪种注射技术,但有些注射比其他注射“更清洁” - 例如,选项1使您无法控制注射方式已完成,选项3表示您的类不能是不可变的。
  2. 如果未绑定Minerals,缺少公共无参数构造函数,并且缺少@Inject构造函数,则Guice会抛出异常,除非您使用@Inject(optional = true)