无法使用guice注入

时间:2015-05-20 09:11:15

标签: guice

我有一个具有以下结构的存档类:

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";

    }
}

我的binder类看起来像这样:

@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);  
    }
}

我得到null配置对象。我无法弄清楚配置为空的原因。有人可以帮我找出原因。

2 个答案:

答案 0 :(得分:2)

你的问题中没有足够的信息来回答它,但我可以给你一些关于在哪里寻找的建议。

Guice试图阻止注入null,因此Archive可能根本没有注入。有几个原因可能发生:

  • 存档有一个@Inject构造函数,不会设置configuration字段
    • 如果两者都可用,Guice可能会选择注入此构造函数而不是@Inject字段。从构造函数中删除@Inject注释。
  • 任何人实例化档案都不是Guice。
    • 您是否正在使用Injector#getInstance()直接实例化Archive,它是否是传感器实例化的某个字段?

答案 1 :(得分:2)

我怀疑configuration为空的原因是因为该类未由Guice创建

为了防止这种情况,提供旨在由Guice创建的类包范围或私有构造函数

public class Archive implements Tasklet, StepExecutionListener {
  private static final String FF = "ff";
  private final Configuration configuration;

  @Inject
  Archive(Configuration configuration) {
    this.configuration = configuration;
  }

  ...

我选择了一个包范围构造函数,因为我想为该类编写单元测试(参见下面的注释)。

如果您希望Archive成为单身人士,请使用@Singleton

为该课程添加注释

以下是上述课程的简单模块:

public class ArchiveModule extends AbstractModule {

  @Override
  protected void configure() {
    bind(Archive.class);
  }
}

实际上并不需要bind()调用 - 模块实际上也不需要 - 但我喜欢它,所以我知道如果安装了模块,Guice会在注入器创建时给出错误,如果它无法为Archive类创建依赖项。

在您的主要内容中,您的代码看起来像这样:

Main main = Guice.createInjector(
    new ArchiveModule(),
    new AnotherModule(),
    ... );
main.run();

一些注意事项:

  • 将@Singleton添加到您的模块无效,因为Guice不构建模块;要求Guice创建注入器的代码通常构造模块。
  • 同样,您的模块未注入,因此模块的injector字段永远不会被设置(除非您在模块上请求静态注入,但我强烈建议不要这样做)
  • 首选构造函数注入字段注入,以便1)您的字段可以是最终的,2)您可以编写创建对象的单元测试而不使用Guice,2)在没有Guice的情况下很难在生产代码中意外创建类。 / LI>
  • 我建议不要使用类名缩写,除非缩写是众所周知的