10

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

Dropwizard 鼓励使用其DbiFactory 来构建 DBI 实例,但为了获得一个,您需要一个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()

到目前为止,我已经能够通过在我的 Commands 中扩展ConfiguredCommandDBI并在它们的方法中创建实例来实现这一点run(),但这是一个糟糕的设计,因为应该将依赖项注入到对象中,而不是在.

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

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

4

2 回答 2

8

你可以使用EnvironmentCommand吗?

于 2014-10-14T19:58:08.083 回答
1

这就是我在 Dropwizard 中使用 Guice 的方式。在您的 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)
  }
}
于 2014-08-31T02:41:12.297 回答