使用guice作为注入类的框架,正确的初始化方法?

时间:2012-12-04 17:51:55

标签: java dependency-injection guice

我正在尝试编写一个框架,其中任意bean类都使用我的API注入类,并且它们可以与这两个类交互,并且基于定义的注释触发了回调。这是一个示例bean:

@Experiment
static class TestExperiment {
    private final HITWorker worker;
    private final ExperimentLog log;
    private final ExperimentController controller;

    @Inject
    public TestExperiment(
        HITWorker worker,
        ExperimentLog expLog,
        ExperimentController controller
        ) {         
        this.worker = worker;
        this.expLog = expLog;
        this.controller = controller;
    }

    @SomeCallback
    void callMeBack() {
        ... do something

        log.print("I did something");
    }

}

我正在尝试使用Guice注入这些bean并处理注入类之间的相互依赖性。但是,我有两个问题:

  • 我传入的其中一个类(HITWorker)已经实例化了。我没看到如何将其移动到Provider而不会使我的代码变得非常复杂。它也是持久的,但不是Guice定义的会话或请求范围,所以我现在自己管理它。 (也许如果其他问题得到克服,我可以尝试将其放在提供者中。)
  • 更重要的是,我需要引用其他注入的类,以便我可以对它们做适当的事情。当Guice注入它们时,我无法访问它们,因为bean类是任意的。

这是我基本上需要做的一些非常糟糕的代码,我确信这违反了所有正确的依赖注入概念。请注意hitw是我需要传入的唯一实例,但我也在创建其他依赖对象,因为我需要引用它们。使用此代码,我基本上只使用Guice作为其反射代码,而不是其依赖性解析。

private void initExperiment(final HITWorkerImpl hitw, final String expId) {         
    final ExperimentLogImpl log = new ExperimentLogImpl();
    final ExperimentControllerImpl cont = new ExperimentControllerImpl(log, expManager);

    // Create an experiment instance with specific binding to this HITWorker
    Injector child = injector.createChildInjector(new AbstractModule() {
        @Override
        protected void configure() {
            bind(HITWorker.class).toInstance(hitw);
            bind(ExperimentLog.class).toInstance(log);
            bind(ExperimentController.class).toInstance(cont);
        }           
    });     

    Object experimentBean = child.getInstance(expClass);        

    expManager.processExperiment(expId, experimentBean);

    // Initialize controller, which also initializes the log
    cont.initialize(expId);

    expManager.triggerStart(expId);

    tracker.newExperimentStarted(expId, hitw, cont.getStartTime());
}

我搞砸了,只需编写自己的注射码,或者有没有办法正确地做到这一点?另外,我应该忘记这些bean类的构造函数注入,因为我不知道它们究竟包含什么?如果我要求Guice注入bean而不是自己动手,有没有办法获得依赖?

就上下文而言,我一直在阅读Guice文档并查看几天的例子,但无济于事。我不认为我是一个完全编程的白痴,但我无法弄清楚如何正确地做到这一点!

1 个答案:

答案 0 :(得分:1)

你的“实验”似乎就像一个“请求”,因为它有一个已定义的生命周期以及实验可以随意引入的一些相关内容。

因此,我认为您应该将所有内容包装到自定义范围中,如有关Custom Scopes的文档中所述。这在几个方面与您的案例相符:

  • 您可以使用某些对象(HITWorker
  • “播种”范围
  • 生命周期:在设置实验之前执行“输入范围”,在完成工作后执行“退出范围”。
  • 访问ExperimentLogExperimentController等“共享”内容:将它们绑定到范围内。然后框架和实验实例都可以简单地@Inject它们并获得相同的实例。