Guice构造函数注入没有注释?

时间:2018-06-13 21:40:30

标签: java dependency-injection guice

有人可以帮助实现带有注释的Guice吗?

public interface IAnimal {
  void makeNoise();
}


public interface IVehicle {
  int getWheelCount();
}





import org.apache.commons.logging.Log;
public class Car implements IVehicle {

    private Log Logger;

    public Car(Log lgr) {
        this.Logger = lgr;
    }

    public final int getWheelCount() {
      this.Logger.info("getWheelCount is returning 4");
      return 4;
    }
}




import org.apache.commons.logging.Log;
public class Dog implements IAnimal {

    private Log Logger;

    public Dog(Log lgr) {
        this.Logger = lgr;
    }

    public final void makeNoise() {
        this.Logger.info("Bark Bark Bark");
    }
}

的pom.xml

    <dependency>
        <groupId>commons-logging</groupId>
        <artifactId>commons-logging</artifactId>
        <version>1.1.3</version>
    </dependency>

    <dependency>
        <groupId>com.google.inject</groupId>
        <artifactId>guice</artifactId>
        <version>4.2.0</version>
    </dependency>

我尝试了什么:

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.google.inject.*;

public class App {

  public static void main(String[] args) {


    Log localLogger = 
        LogFactory.getLog(App.class);

    Injector injector = Guice.createInjector();

    IVehicle veh = injector.getInstance(Car.class);  
    int wc = veh.getWheelCount();

    IAnimal amh = injector.getInstance(Dog.class);  
    amh.makeNoise();
  }
}

我得到的错误是:

Classes must have either one (and only one) constructor annotated with @Inject or a zero-argument constructor that is not private.

我理解错误。

但是我希望我可以将Guice“指向”正确的构造函数......而不是使用注释。

正如你所看到的,使用默认/空构造函数不是一个好选择,因为这个例子很简单,但我想坚持使用基于构造函数的注入。

APPEND:

基于我在评论中从Hemant Singh那里得到的“提示”,我想我离得更近了。

我创建了一个使用

的ProductionInjectModule
bind(MyInterface.class).toConstructor(MyConcrete.class.getConstructor(org.apache.commons.logging.Log.class));

但即使我通过指向一个特定的构造函数来“强迫”这个问题(使用“toConstructor”).......我还是得到了:

  

类必须有一个(并且只有一个)带注释的构造函数   @Inject或非私有的零参数构造函数。

Gaaaaaaaaaaaaaaaaaaaaa!

以下完整的“模块”代码:

public class App {

  public static void main(String[] args) {
    runGuice();

  }

  private static void runGuice() {
    Log localLogger = LogFactory.getLog(App.class);

    ProductionInjectModule pm = new ProductionInjectModule(localLogger);
    Injector injector = Guice.createInjector(pm);
    ////Injector injector = Guice.createInjector();
    //// injector.injectMembers(localLogger);

    IVehicle veh = injector.getInstance(Car.class);
    int wc = veh.getWheelCount();

    IAnimal amh = injector.getInstance(Dog.class);
    amh.makeNoise();
  }

 }




import com.google.inject.AbstractModule;
import com.google.inject.Module;

public class ProductionInjectModule extends AbstractModule implements Module {
  // public void configure(Binder binder) {
  // binder.bind(IVehicle.class).to(Car.class);
  //// binder.bind(InterfaceB.class).to(ConcreteB.class);
  //// binder.bind(InterfaceC.class).to(ConcreteC.class);
  // }

  private final org.apache.commons.logging.Log Logger;

  public ProductionInjectModule(org.apache.commons.logging.Log concreteLogger) {
    this.Logger = concreteLogger;
  }

  @Override
  protected void configure() {
    try {
      bind(org.apache.commons.logging.Log.class).toInstance(this.Logger);
      bind(IVehicle.class).toConstructor(Car.class.getConstructor(org.apache.commons.logging.Log.class));
      bind(IAnimal.class).toConstructor(Dog.class.getConstructor(org.apache.commons.logging.Log.class));
    } catch (NoSuchMethodException e) {
      addError(e);
    }
  }

}

按照同样的提示,我找到了一些支持的文档:

来自:http://www.baeldung.com/guice

  

您还可以注入没有默认no-arg的依赖项   使用构造函数绑定的构造函数:

>     public class BasicModule extends AbstractModule {
>   
>     @Override
>     protected void configure() {
>         bind(Boolean.class).toInstance(true);
>         bind(Communication.class).toConstructor(
>           Communication.class.getConstructor(Boolean.TYPE)); } 
The snippet above will inject an instance of Communication using the
     

带有布尔参数的构造函数。我们提供真正的论点   通过定义布尔的非目标绑定来构造函数   类。

     

这个无目标的绑定将被热切地提供给任何构造函数   接受布尔参数的绑定。通过这种方法,所有   注入了沟通的依赖性。

     

构造函数特定绑定的另一种方法是实例   绑定,我们直接在绑定中提供实例:

>     public class BasicModule extends AbstractModule {
>   
>     @Override
>     protected void configure() {
>         bind(Communication.class)
>           .toInstance(new Communication(true));
>     }     }

1 个答案:

答案 0 :(得分:2)

我明白了!我原来问题中的“APPEND:”区域很接近!但现在我看到了我的小错误。

上面的我的ProductionInjectModule是正确的。

我的“要求解决”是错误的。

请注意,在我的getInstance中,我仍然具体。

我需要这样:(强调getInstance的参数)

IVehicle veh = injector.getInstance(IVehicle.class);
int wc = veh.getWheelCount();

IAnimal amh = injector.getInstance(IAnimal.class);
amh.makeNoise();

完整的工作代码:(使用上面的接口和混凝土)

public class App {

  public static void main(String[] args) {
    runGuice();

  }

  private static void runGuice() {
    Log localLogger = LogFactory.getLog(App.class);

    ProductionInjectModule pm = new ProductionInjectModule(localLogger);
    Injector injector = Guice.createInjector(pm);

    IVehicle veh = injector.getInstance(IVehicle.class);
    int wc = veh.getWheelCount();

    IAnimal amh = injector.getInstance(IAnimal.class);
    amh.makeNoise();
  }

 }




import com.google.inject.AbstractModule;
import com.google.inject.Module;

public class ProductionInjectModule extends AbstractModule implements Module {

  private final org.apache.commons.logging.Log Logger;

  public ProductionInjectModule(org.apache.commons.logging.Log concreteLogger) {
    this.Logger = concreteLogger;
  }

  @Override
  protected void configure() {
    try {
      bind(org.apache.commons.logging.Log.class).toInstance(this.Logger);
      bind(IVehicle.class).toConstructor(Car.class.getConstructor(org.apache.commons.logging.Log.class));
      bind(IAnimal.class).toConstructor(Dog.class.getConstructor(org.apache.commons.logging.Log.class));
    } catch (NoSuchMethodException e) {
      addError(e);
    }
  }

}