Guice:使用@Named注释的字段值为null

Tej*_*tha 1 java guice

我有一个类,我声明我的静态常量:

public final class ConfigOptions {
    public static final String FILE_PATH_SERVER = "/home/user/me/somefile";
}
Run Code Online (Sandbox Code Playgroud)

然后我用Guice将它绑定在我的ServletModule:

public class MyServletModule extends ServletModule {
    bind(String.class).annotatedWith(Names.named("filePath"))
        .toInstance(ConfigOptions.FILE_PATH_SERVER);

    // Also tried
    // bindConstant().annotatedWith(Names.named("filePath")).to(ConfigOptions.FILE_PATH_SERVER)

    // ... other bindings
}
Run Code Online (Sandbox Code Playgroud)

我的GuiceServletContextListener:

public class MyServletContextListener extends GuiceServletContextListener {

    @Override
    protected Injector getInjector() {
        return Guice.createInjector(new MyServletModule());
    }
}
Run Code Online (Sandbox Code Playgroud)

最后,我尝试使用filePath:

public class MyClass {

    @Inject
    @Named("filePath")
    private String filePath;

    public MyClass() { ... }

    public void doSomething() {
        someotherThing.setFilePath(filePath);  // But filePath is null
    }
}
Run Code Online (Sandbox Code Playgroud)

我主要是按照这里显示的方法,但不确定我是否遗漏了一些东西.

此外,我已确保import com.google.inject.name.Named导入正确的.

Jef*_*ica 5

确认你是让Guice创建你的MyClass实例,而不是自己实例化它们new MyClass().即使字段被标记@Inject,Guice也只能设置值,如果Guice负责创建包含它的实例*.通过现场注入,如果从未通过注入器请求类,则该字段将静默保持为空.

切换到构造函数注入也有助于明确是否通过Guice提供类,因为更改构造函数本身会破坏任何直接调用而不会破坏Guice创建的引用:

public class MyClass {

  private final String filePath;

  @Inject public MyClass(@Named("filePath") String filePath) {
    this.filePath = filePath;
    // ...
  }

  // ...
}
Run Code Online (Sandbox Code Playgroud)

*您也可以使用Injector.injectMembers(instance)Binder.requestInjection(instance)将Guice注入现有实例.这些并不常见,并且可能使您难以遵循构造和注入实例的位置,但可能在遗留代码和其他一些情况下证明是有用的.