将Guice单例服务注入到Quartz任务,Stripes ActionBeans和ServletContextListeners中的正确方法是什么?

时间:2013-09-02 07:57:16

标签: java dependency-injection guice guice-3

目前我正在使用静态单例来获取Guice 3.0通过DI为我构建的单例服务 - 我相信这是一个可怕的黑客攻击并且根本没有将Guice用于DI的预期方式,并使单元测试变得复杂

public class ServiceProvider {
    private static ServiceProvider instance = new ServiceProvider();    
    private MyService myService;

    public ServiceProvider() {      
        Injector myInjector = Guice.createInjector(new MyModule());
        myService = noobmeterInjector.getInstance(MyService.class);
    }

    public static MyService getMyService() {
        return instance.myService;
    }
}

但是,我不太清楚如何解决这个问题,因为我至少需要在四个不同的地方提供这项服务:

  • Stripes ActionBeans - 我认为Stripes Guice plugin会帮助我,我确实连接了它,但最终得到了多个并行的MyServices
  • ServletContextListener - 我认为Guice Servlet module可能会以某种方式提供帮助,尽管我正在努力学习文档,因为它主要讨论用Guice配置替换web.xml(此时不是我的优先级)并将HttpServletRequests注入Guice - 构建的对象(再次不是我想要做的)
  • Quartz Jobs - 在这里我找到something relevant,但不确定它是否会最终仍然为其他人创建“并行”MyService
  • 从命令行运行批处理 - 这是容易的部分

MyService服务旨在成为一个单独的服务(它拥有开放式DB / MQ连接等的其他服务,因此创建其中的多个服务会很糟糕)。

在Guice中有一些简单的方法可以解决这个问题吗?

1 个答案:

答案 0 :(得分:0)

因此,您的代码段存在一些问题。

  • 您不应再将单例作为静态变量实现;让Guice为您做生命周期管理。
  • 在此示例中,ServiceProvider基本上是一个服务定位器实现,因为您使用的是Guice,所以这是不必要的。
  • 优良作法是尽可能保持Injector创作“高”。服务器启动的main方法是一个好地方。

我添加了一些代码来演示。

public class Server {
    public static void main(String[] args) {
        Injector injector = Guice.createInjector(new MyModule());
        // Your code here.
    }
}

public class MyModule extends AbstractModule {
    protected void configure() {
         // Assuming MyService implements Service
         bind(Service.class).to(MyService.class).in(Singleton.class);
    }
}