Java 我可以使用Guice在方法中获取实例吗?
我刚开始使用Guice,所以我的理解可能是完全错误的 我有一个接口Foo和一个实现FooImp 我在模块中使用了以下代码来注入它: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
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。通常使用这种方法。当涉及复杂类时,使用提供程序更常用。