无法使用 guice 注入
Unable to inject using guice
我有一个档案 class 具有以下结构:
public class Archive implements Tasklet, StepExecutionListener{
@Inject
private Configuration configuration;
public static final String FF = "ff";
@Override
public RepeatStatus execute(StepContribution arg0, ChunkContext arg1)
throws Exception {
System.out.println("in execute method :)");
return RepeatStatus.FINISHED;
}
@Override
public ExitStatus afterStep(StepExecution arg0) {
return ExitStatus.COMPLETED;
}
@Override
public void beforeStep(StepExecution arg0) {
JobExecution jobExecution = arg0.getJobExecution();
ExecutionContext jobContext = jobExecution.getExecutionContext();
Properties properties = configuration.getPrefixProperties(FF);
filePath = properties.getProperty("fd.folder");
fileName = "test.csv";
}
}
我的活页夹 class 看起来像这样:
@Singleton
public class EWM extends AbstractModule {
@Inject
private static Injector injectorInstance;
private static final EWM instance = new EWM();
public static final EWM getInstance() {
return instance;
}
public static Injector getInjector() {
return injectorInstance;
}
public EWM() {
}
@Override
protected void configure() {
bind(Archive.class);
requestInjection(LoggingAspect.class);
}
}
我得到空配置对象。我无法弄清楚配置为空的原因。谁能帮我找出原因。
你的问题中没有足够的信息来回答它,但我可以给你一些建议,告诉你去哪里找。
Guice 试图阻止注入 null,因此很可能根本没有注入 Archive。可能发生的原因有几个:
- Archive 有一个
@Inject
构造函数,它没有设置 configuration
字段
- Guice 可能会选择注入此构造函数而不是
@Inject
字段(如果两者都可用)。从构造函数中删除 @Inject
注释。
- 实例化 Archive 的人不是 Guice。
- 您是否使用
Injector#getInstance()
直接实例化 Archive,它是否传递了注入器正在实例化的对象上的一个字段?
我怀疑 configuration
为空的原因是因为 class 不是由 Guice 创建的。
为防止这种情况发生,为 Guice 设计的 classes 提供包范围或私有构造函数:
public class Archive implements Tasklet, StepExecutionListener {
private static final String FF = "ff";
private final Configuration configuration;
@Inject
Archive(Configuration configuration) {
this.configuration = configuration;
}
...
我选择了包范围的构造函数,因为我想为 class 编写单元测试(参见下面的注释)。
如果你想让Archive
成为单例,用@Singleton
注释class
这里是上面的一个简单模块class:
public class ArchiveModule extends AbstractModule {
@Override
protected void configure() {
bind(Archive.class);
}
}
实际上并不需要 bind()
调用——实际上也不需要模块——但我喜欢它,所以我知道如果安装了模块,Guice 将在注入器创建时给出错误如果它无法为 Archive
class.
创建依赖项
在您的 main 中,您的代码看起来像这样:
Main main = Guice.createInjector(
new ArchiveModule(),
new AnotherModule(),
... );
main.run();
一些注意事项:
- 将@Singleton 添加到您的模块没有任何效果,因为 Guice 不构建模块;要求 Guice 创建注入器的代码通常会构建模块。
- 同样,你的模块没有被注入,所以你的模块的
injector
字段永远不会被设置(除非你请求对模块进行静态注入,但我强烈建议不要那样做)
- 优先使用构造函数注入而不是字段注入,因此 1) 您的字段可以是最终的,2) 您可以编写单元测试来创建对象而不使用 Guice,并且 2) 很难意外地创建 class没有 Guice 的生产代码。
- 我建议不要对 class 名称使用缩写,除非缩写是众所周知的
我有一个档案 class 具有以下结构:
public class Archive implements Tasklet, StepExecutionListener{
@Inject
private Configuration configuration;
public static final String FF = "ff";
@Override
public RepeatStatus execute(StepContribution arg0, ChunkContext arg1)
throws Exception {
System.out.println("in execute method :)");
return RepeatStatus.FINISHED;
}
@Override
public ExitStatus afterStep(StepExecution arg0) {
return ExitStatus.COMPLETED;
}
@Override
public void beforeStep(StepExecution arg0) {
JobExecution jobExecution = arg0.getJobExecution();
ExecutionContext jobContext = jobExecution.getExecutionContext();
Properties properties = configuration.getPrefixProperties(FF);
filePath = properties.getProperty("fd.folder");
fileName = "test.csv";
}
}
我的活页夹 class 看起来像这样:
@Singleton
public class EWM extends AbstractModule {
@Inject
private static Injector injectorInstance;
private static final EWM instance = new EWM();
public static final EWM getInstance() {
return instance;
}
public static Injector getInjector() {
return injectorInstance;
}
public EWM() {
}
@Override
protected void configure() {
bind(Archive.class);
requestInjection(LoggingAspect.class);
}
}
我得到空配置对象。我无法弄清楚配置为空的原因。谁能帮我找出原因。
你的问题中没有足够的信息来回答它,但我可以给你一些建议,告诉你去哪里找。
Guice 试图阻止注入 null,因此很可能根本没有注入 Archive。可能发生的原因有几个:
- Archive 有一个
@Inject
构造函数,它没有设置configuration
字段- Guice 可能会选择注入此构造函数而不是
@Inject
字段(如果两者都可用)。从构造函数中删除@Inject
注释。
- Guice 可能会选择注入此构造函数而不是
- 实例化 Archive 的人不是 Guice。
- 您是否使用
Injector#getInstance()
直接实例化 Archive,它是否传递了注入器正在实例化的对象上的一个字段?
- 您是否使用
我怀疑 configuration
为空的原因是因为 class 不是由 Guice 创建的。
为防止这种情况发生,为 Guice 设计的 classes 提供包范围或私有构造函数:
public class Archive implements Tasklet, StepExecutionListener {
private static final String FF = "ff";
private final Configuration configuration;
@Inject
Archive(Configuration configuration) {
this.configuration = configuration;
}
...
我选择了包范围的构造函数,因为我想为 class 编写单元测试(参见下面的注释)。
如果你想让Archive
成为单例,用@Singleton
这里是上面的一个简单模块class:
public class ArchiveModule extends AbstractModule {
@Override
protected void configure() {
bind(Archive.class);
}
}
实际上并不需要 bind()
调用——实际上也不需要模块——但我喜欢它,所以我知道如果安装了模块,Guice 将在注入器创建时给出错误如果它无法为 Archive
class.
在您的 main 中,您的代码看起来像这样:
Main main = Guice.createInjector(
new ArchiveModule(),
new AnotherModule(),
... );
main.run();
一些注意事项:
- 将@Singleton 添加到您的模块没有任何效果,因为 Guice 不构建模块;要求 Guice 创建注入器的代码通常会构建模块。
- 同样,你的模块没有被注入,所以你的模块的
injector
字段永远不会被设置(除非你请求对模块进行静态注入,但我强烈建议不要那样做) - 优先使用构造函数注入而不是字段注入,因此 1) 您的字段可以是最终的,2) 您可以编写单元测试来创建对象而不使用 Guice,并且 2) 很难意外地创建 class没有 Guice 的生产代码。
- 我建议不要对 class 名称使用缩写,除非缩写是众所周知的