子模块的故障安全注入器。 google guice 中的可选绑定
Fail-safe injector for child modules. Optional bindings in google guice
我有一个名为 ChildPlugin 的子模块,我从主模块注入 类 如下:
public class ChildPlugin {
private ExampleClass demo;
@Inject
public void setDemo(ExampleClass demo) {
this.demo = demo;
}
}
问题是我不知道主模块是否绑定 ExampleClass
,如果不是,Guice 在创建注入器时会抛出异常。我想要做的是让 Guice 通过 null
或 Optional.empty
如果 ExampleClass 没有绑定。
我无法访问主模块,所以我无法将 ExampleClass
的活页夹更改为 OptionalBinder
,我在 [=19= 中尝试了 @Nullable
和 Optional<ExampleClass>
] 方法,但没有用。
有两种方法可以做到这一点。
可选注入
使用 com.google.inject.Inject 注释。这允许您在注释上指定可选的。看这个例子:
public class GuiceInjectOptional extends AbstractModule {
@Override
protected void configure() {
// method 1:
bind(B.class).in(Singleton.class);
}
public static class A {
private String name;
// non null constructor so that A can't be instantiated automatically by guice
public A(String name) {
this.name = name;
}
@Override
public String toString() {
return "I am: " + name;
}
}
public static class B {
@Inject(optional=true)
A obj;
void run() {
System.out.println("Object is: " + obj);
}
}
public static void main(String[] args) {
Injector injector = Guice.createInjector(new GuiceInjectOptional());
injector.getInstance(B.class).run();;
}
}
class B 上的注释表示 A 是可选的。它不会被注射。 运行 片段打印:
Object is: null
方法 2(这是您在 guice 4+ 之后执行此操作的方法)。您可以指定可选绑定。如果您愿意,这些绑定甚至允许您定义默认值。然后你可以像我写的这个片段一样注入一个可选值:
public class GuiceInjectOptional extends AbstractModule {
@Override
protected void configure() {
// set up optional binding for A.
OptionalBinder.newOptionalBinder(binder(), A.class);
bind(B.class).in(Singleton.class);
}
public static class A {
private String name;
// non null constructor so that A can't be instantiated automatically by guice
public A(String name) {
this.name = name;
}
@Override
public String toString() {
return "I am: " + name;
}
}
public static class B {
@Inject
Optional<A> obj;
void run() {
System.out.println("Object is present: " + obj.isPresent());
System.out.println("Object is: " + obj);
}
}
public static void main(String[] args) {
Injector injector = Guice.createInjector(new GuiceInjectOptional());
injector.getInstance(B.class).run();;
}
}
Inject 注释现在是非可选的,但 guice 知道 class A 可能已绑定也可能未绑定。
运行 片段将打印:
Object is present: false
Object is: Optional.empty
最后,您可以正常绑定 A,guice 将注入它:
public class GuiceInjectOptional extends AbstractModule {
@Override
protected void configure() {
// set up optional binding for A.
OptionalBinder.newOptionalBinder(binder(), A.class);
bind(A.class).toInstance(new A("Pandaa!"));
bind(B.class).in(Singleton.class);
}
public static class A {
private String name;
// non null constructor so that A can't be instantiated automatically by guice
public A(String name) {
this.name = name;
}
@Override
public String toString() {
return "I am: " + name;
}
}
public static class B {
@Inject
Optional<A> obj;
void run() {
System.out.println("Object is present: " + obj.isPresent());
System.out.println("Object is: " + obj);
}
}
public static void main(String[] args) {
Injector injector = Guice.createInjector(new GuiceInjectOptional());
injector.getInstance(B.class).run();;
}
}
以上将打印:
Object is present: true
Object is: Optional[I am: Pandaa!]
这就是您使用 guice 进行故障安全可选绑定的方式 :) 希望这对您有所帮助。
编辑:我刚看到 guice-3 标签,所以您需要使用可选的注释方法而不是可选的活页夹。使用可选注释,它将保持为 null 而不是可选值。
阿图尔
我有一个名为 ChildPlugin 的子模块,我从主模块注入 类 如下:
public class ChildPlugin {
private ExampleClass demo;
@Inject
public void setDemo(ExampleClass demo) {
this.demo = demo;
}
}
问题是我不知道主模块是否绑定 ExampleClass
,如果不是,Guice 在创建注入器时会抛出异常。我想要做的是让 Guice 通过 null
或 Optional.empty
如果 ExampleClass 没有绑定。
我无法访问主模块,所以我无法将 ExampleClass
的活页夹更改为 OptionalBinder
,我在 [=19= 中尝试了 @Nullable
和 Optional<ExampleClass>
] 方法,但没有用。
有两种方法可以做到这一点。
可选注入
使用 com.google.inject.Inject 注释。这允许您在注释上指定可选的。看这个例子:
public class GuiceInjectOptional extends AbstractModule {
@Override
protected void configure() {
// method 1:
bind(B.class).in(Singleton.class);
}
public static class A {
private String name;
// non null constructor so that A can't be instantiated automatically by guice
public A(String name) {
this.name = name;
}
@Override
public String toString() {
return "I am: " + name;
}
}
public static class B {
@Inject(optional=true)
A obj;
void run() {
System.out.println("Object is: " + obj);
}
}
public static void main(String[] args) {
Injector injector = Guice.createInjector(new GuiceInjectOptional());
injector.getInstance(B.class).run();;
}
}
class B 上的注释表示 A 是可选的。它不会被注射。 运行 片段打印:
Object is: null
方法 2(这是您在 guice 4+ 之后执行此操作的方法)。您可以指定可选绑定。如果您愿意,这些绑定甚至允许您定义默认值。然后你可以像我写的这个片段一样注入一个可选值:
public class GuiceInjectOptional extends AbstractModule {
@Override
protected void configure() {
// set up optional binding for A.
OptionalBinder.newOptionalBinder(binder(), A.class);
bind(B.class).in(Singleton.class);
}
public static class A {
private String name;
// non null constructor so that A can't be instantiated automatically by guice
public A(String name) {
this.name = name;
}
@Override
public String toString() {
return "I am: " + name;
}
}
public static class B {
@Inject
Optional<A> obj;
void run() {
System.out.println("Object is present: " + obj.isPresent());
System.out.println("Object is: " + obj);
}
}
public static void main(String[] args) {
Injector injector = Guice.createInjector(new GuiceInjectOptional());
injector.getInstance(B.class).run();;
}
}
Inject 注释现在是非可选的,但 guice 知道 class A 可能已绑定也可能未绑定。 运行 片段将打印:
Object is present: false
Object is: Optional.empty
最后,您可以正常绑定 A,guice 将注入它:
public class GuiceInjectOptional extends AbstractModule {
@Override
protected void configure() {
// set up optional binding for A.
OptionalBinder.newOptionalBinder(binder(), A.class);
bind(A.class).toInstance(new A("Pandaa!"));
bind(B.class).in(Singleton.class);
}
public static class A {
private String name;
// non null constructor so that A can't be instantiated automatically by guice
public A(String name) {
this.name = name;
}
@Override
public String toString() {
return "I am: " + name;
}
}
public static class B {
@Inject
Optional<A> obj;
void run() {
System.out.println("Object is present: " + obj.isPresent());
System.out.println("Object is: " + obj);
}
}
public static void main(String[] args) {
Injector injector = Guice.createInjector(new GuiceInjectOptional());
injector.getInstance(B.class).run();;
}
}
以上将打印:
Object is present: true
Object is: Optional[I am: Pandaa!]
这就是您使用 guice 进行故障安全可选绑定的方式 :) 希望这对您有所帮助。
编辑:我刚看到 guice-3 标签,所以您需要使用可选的注释方法而不是可选的活页夹。使用可选注释,它将保持为 null 而不是可选值。
阿图尔