Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/349.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 我可以使用Guice在方法中获取实例吗?_Java_Dependency Injection_Guice - Fatal编程技术网

Java 我可以使用Guice在方法中获取实例吗?

Java 我可以使用Guice在方法中获取实例吗?,java,dependency-injection,guice,Java,Dependency Injection,Guice,我刚开始使用Guice,所以我的理解可能是完全错误的 我有一个接口Foo和一个实现FooImp 我在模块中使用了以下代码来注入它: bind(Foo.class).annotatedWith("Foo").toInstance(foo); // foo is an instance of FooImp 那么,我想现在在我的代码中,一个名为Foo注释的Foo实例将被Foo替换到哪里 如果我是对的,我怎样才能做到这一点: public Foo doSomething() { // for so

我刚开始使用Guice,所以我的理解可能是完全错误的

我有一个接口Foo和一个实现FooImp

我在模块中使用了以下代码来注入它:

bind(Foo.class).annotatedWith("Foo").toInstance(foo);  // foo is an instance of FooImp
那么,我想现在在我的代码中,一个名为Foo注释的Foo实例将被Foo替换到哪里

如果我是对的,我怎样才能做到这一点:

public Foo doSomething() {  // for some reason there must be no arguments
    @Named("Foo")
    Foo fooInst;   // injecting here seems not allowed...?
    fooInst.do();
}

不幸的是,您不能在局部变量上放置注释。这个限制来自Java,而不是Guice。据我们所知,我们希望在未来的Java版本中获得这一特性


但请注意,即使这样做可行,也不是一个好的做法。依赖项注入的思想是从类外部更改依赖项的能力。局部变量不适用于此,因为它不能从类外部更改。

不幸的是,您不能在局部变量上放置注释。这个限制来自Java,而不是Guice。据我们所知,我们希望在未来的Java版本中获得这一特性


但请注意,即使这样做可行,也不是一个好的做法。依赖项注入的思想是从类外部更改依赖项的能力。局部变量不适合这种情况,因为它不能从类外部进行更改。

您所假设的不完全正确:Guice用于依赖项注入,这意味着您可以将某些接口/类注入到另一个类的构造函数中

假设您有一个接口Foo及其实现FooImpl。然后还有一个类栏,它取决于Foo的实现

在Guice模块中,您必须编写

bind(Foo.class).annotatedWith(Names.named("Foo")).toInstance(foo);
//let's say this is part of the module MyModule extends AbstractModule
设置好之后,就可以创建一个main方法,使用Guice的Injector类创建一个对象。像这样:

Injector injector = Guice.createInjector(new MyModule());
Bar bar = injector.getInstance(Bar.class);
//do something with bar
希望这对你有所帮助。如果你有更多的问题,请随时问我

提示:查看的网站,观看视频,仔细阅读维基。Guice是一个非常好的工具,但是在使用它之前需要做一些研究。 祝你好运

另外:在我看来,使用@Named是一种糟糕的代码风格。您可以更好地定义自己的注释。例如:

@BindingAnnotation
@Target({ FIELD, PARAMETER, METHOD })
@Retention(RUNTIME)
public @interface FooAnnotation {
}

然后在Bar类中将@Namedfoo替换为@FooAnnotation,并将模块中的Names.Namedfoo替换为FooAnnotation.class。

您假设的不完全正确:Guice用于依赖项注入,这意味着您可以将一些接口/类注入到另一个类的构造函数中

假设您有一个接口Foo及其实现FooImpl。然后还有一个类栏,它取决于Foo的实现

在Guice模块中,您必须编写

bind(Foo.class).annotatedWith(Names.named("Foo")).toInstance(foo);
//let's say this is part of the module MyModule extends AbstractModule
设置好之后,就可以创建一个main方法,使用Guice的Injector类创建一个对象。像这样:

Injector injector = Guice.createInjector(new MyModule());
Bar bar = injector.getInstance(Bar.class);
//do something with bar
希望这对你有所帮助。如果你有更多的问题,请随时问我

提示:查看的网站,观看视频,仔细阅读维基。Guice是一个非常好的工具,但是在使用它之前需要做一些研究。 祝你好运

另外:在我看来,使用@Named是一种糟糕的代码风格。您可以更好地定义自己的注释。例如:

@BindingAnnotation
@Target({ FIELD, PARAMETER, METHOD })
@Retention(RUNTIME)
public @interface FooAnnotation {
}

然后在Bar类中将@Namedfoo替换为@FooAnnotation,并将模块中的Names.Namedfoo替换为FooAnnotation.class。

其他答案都是正确的,您只能将其插入构造函数或字段中。将实例保留为字段是标准做法,这也允许您在自己的实现中交换以进行测试

如果每次调用方法时都需要生成新实例,则可以使用提供程序。对于Foo或@Baz Foo的任何给定绑定,Provider或@Baz Provider都不需要任何额外的代码

public class Bar {
  private Provider<Foo> fooProvider;

  @Inject
  public Bar(@Named("foo") Provider<Foo> fooProvider) {
    this.fooProvider = fooProvider;
  }

  public doSomething() {
    Foo foo = fooProvider.get();
  }
}

当然,按照bind…toInstance…的方式,它始终是同一个实例,但如果每次运行方法都需要一个新实例,这是您的最佳选择。

其他答案都是正确的,您只能将其注入构造函数或字段。将实例保留为字段是标准做法,这也允许您在自己的实现中交换以进行测试

如果每次调用方法时都需要生成新实例,则可以使用提供程序。对于Foo或@Baz Foo的任何给定绑定,Provider或@Baz Provider都不需要任何额外的代码

public class Bar {
  private Provider<Foo> fooProvider;

  @Inject
  public Bar(@Named("foo") Provider<Foo> fooProvider) {
    this.fooProvider = fooProvider;
  }

  public doSomething() {
    Foo foo = fooProvider.get();
  }
}

当然,按照bind…toInstance…的方式,它始终是同一个实例,但如果每次运行方法都需要一个新实例,这是您的最佳选择。

清楚而有用的答案。谢谢你的帮助!清楚而有用的答案。谢谢你的帮助!我不认为这是答案,因为Rvan的帮助更大。不过还是很有帮助的答案。谢谢。我不认为这是答案,因为Rvan的帮助更大。不过还是很有帮助的答案。谢谢。我刚接受你的邀请,你就回答了我的问题
那…我以后再查。谢谢您对新实例和始终相同实例的评论是正确的。我大部分时间做的是:bindFoo.class.annotatedWith…toFooImp.class。通常使用这种方法。当涉及复杂类时,使用提供程序更常用。在我接受另一个问题后,您刚刚回答了我的问题…我稍后会检查。谢谢您对新实例和始终相同实例的评论是正确的。我大部分时间做的是:bindFoo.class.annotatedWith…toFooImp.class。通常使用这种方法。当涉及复杂类时,使用提供程序更常用。