如何将jdbiFactory DAO注入Dropwizard命令?

时间:2014-03-11 08:20:03

标签: java dependency-injection dropwizard jdbi

我开始使用Dropwizard,我正在尝试创建一个需要使用数据库的Command。如果有人想知道我为什么要这样做,我可以提供充分的理由,但无论如何这不是我的问题。它是关于依赖倒置和服务初始化以及Dropwizard中的运行阶段。

Dropwizard鼓励使用它的DbiFactory to build DBI instances但是为了得到它,你需要一个Environment实例和/或数据库配置:

public class ConsoleService extends Service<ConsoleConfiguration> {

  public static void main(String... args) throws Exception {
    new ConsoleService().run(args);
  }

  @Override
  public void initialize(Bootstrap<ConsoleConfiguration> bootstrap) {
    bootstrap.setName("console");
    bootstrap.addCommand(new InsertSomeDataCommand(/** Some deps should be here **/));
  }

  @Override
  public void run(ConsoleConfiguration config, Environment environment) throws ClassNotFoundException {
    final DBIFactory factory = new DBIFactory();
    final DBI jdbi = factory.build(environment, config.getDatabaseConfiguration(), "postgresql");
    // This is the dependency I'd want to inject up there
    final SomeDAO dao = jdbi.onDemand(SomeDAO.class); 
  }
}

如您所见,您在run()方法中拥有服务及其环境的配置,但需要在其initialize()方法中将命令添加到服务的引导程序中。

到目前为止,我已经通过在我的命令中扩展ConfiguredCommand并在DBI方法中创建run()个实例来实现这一目标,但这是一个糟糕的设计,因为{ {3}}。

我更喜欢通过构造函数注入我的命令的DAO或任何其他依赖项,但这对我来说似乎是不可能的,因为Environment和配置在服务初始化时是不可访问的,当我需要时创建并将它们添加到引导程序中。

有谁知道如何实现这个目标?

2 个答案:

答案 0 :(得分:8)

您可以使用EnvironmentCommand吗?

答案 1 :(得分:1)

这就是我如何使用Guice和Dropwizard。在run()方法内添加行

Guice.createInjector(new ConsoleModule());

创建类ConsoleModule

public class ConsoleModule extends AbstractModule {

 public  ConsoleModule(ConsoleConfiguration consoleConfig)
 {
     this.consoleConfig = consoleConfig;
 }

 protected void configure()
{
   bind(SomeDAO.class).to(SomeDAOImpl.class).in(Singleton.class)
  }
}