java - Guice - 字段注入(inject)限制

标签 java dependency-injection guice guice-3

假设我们有一个名为 Bean 的类,它依赖于另一个名为 Service 的类,使用 Fields Injection我们不能更改这些类的代码。另一个类 (App) 使用 Provider 以便在需要时构造 Bean 的新实例,我们可以自由更改这些类中的代码。

由于在 Providerget() 方法中,新实例是使用 new 运算符创建的,因此不可能注入(inject) ServiceBean 中,因此 Bean 实例将不完整(Service 字段将为 null)。

绕过该问题的一种方法是在 Provider 中注入(inject) Injector 并在 get() 中调用 injector.injectMembers() > 方法,在新实例上。

代码示例如下(我避免使用接口(interface)来缩短代码)。

class Bean {
    @Inject private Service service;

    public Bean() {
    }

    public void bar() {
        this.service.foo();
    }
}

class Service {

    public void foo() {
        System.out.println("foo");
    }
}

class App {
    @Inject private Provider<Bean> beanProvider;

    public App() {
    }

    public void run() {
        this.beanProvider.get().bar();
    }
}

class BeanProvider implements Provider<Bean> {
    @Inject Injector injector;

    public Bean get() {
        Bean mybean = new Bean();
        this.injector.injectMembers(mybean);

        return mybean;
    }
}

// A simple module to bind the classes
class MyModule extends AbstractModule {

    @Override
    protected void configure() {
        bind(Service.class);
        bind(Bean.class).toProvider(BeanProvider.class);
        bind(App.class);
    }
}


public static void main(String[] args) {
    Injector injector = Guice.createInjector(new MyModule());
    injector.getInstance(App.class).run();
}

另一种方法是将 Bean 更改为使用构造注入(inject),但正如我所说,让我们假设我们不能那样做。

我知道大多数人声称应该避免注入(inject) Injector,因为它打破了整个 DI 哲学,因为注入(inject)器应该只在应用程序的入口点而不是其他地方使用,但是因为Guice 提供了在应用程序中使用 DI 的不同方式,例如 Field Injection,可能会出现我描述的情况。此外,我已经看到在多个项目中经常使用字段注入(inject),因此经常会出现这种情况。

那么,是否有一种“更干净”的方法来避免在我描述的问题中注入(inject) Injector

最佳答案

这看起来应该不是您的模块的问题。看起来您根本不需要创建提供程序。

您在模块中设置的绑定(bind)应该会导致 Service 在您需要的任何地方注入(inject)到 Bean 中。因此,您应该能够用 Bean 注入(inject)替换 App 中的提供者声明。

class App {
     @Inject private Bean beanObject;

     public App() {
     }

     public void run() {
         this.beanObject.bar();
     }
}

// A simple module to bind the classes
class MyModule extends AbstractModule {
    @Override
    protected void configure() {
        //bind this to whatever you want to inject into Bean...
        bind(Service.class); 
        bind(Bean.class);
        bind(App.class);
    }
}

如果这对您不起作用,您能否说明您正在尝试做什么以及为什么需要提供商?

关于java - Guice - 字段注入(inject)限制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22364274/

相关文章:

java - 如何使用 Guice 注入(inject) HK2 beans

java - Guice 嵌套泛型类型绑定(bind)

Java泛型?

java - SpringSource和以前的Spring是一回事吗? :)

java - 我已经安装了 Berkeley DB 5.1.25.msi Windows 安装程序

java - setBackgroundDrawable 在 android 中给出 nullpointerexception

c# - 使用 Controller 类以外的类进行依赖注入(inject)

dependency-injection - 类库中带有 Ninject 的 DI

c# - ASP.NET Core 中的依赖注入(inject)

java - Guice @Transactional 不启动事务