How do you inject jdbiFactory DAOs into a Dropwiza

2019-06-16 04:25发布

I'm starting to work with Dropwizard and I'm trying to create a Command that requires to use the database. If someone is wondering why I'd want to do that, I can provide good reasons, but this is not the point of my question anyway. It's about dependency inversion and Service initialization and run phases in Dropwizard.

Dropwizard encourages to use its DbiFactory to build DBI instances but in order to get one, you need an Environment instance and/or the database configuration:

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

As you can see, you have the configuration for your Service and its Environment in its run() method, but commands need to be added to the Service's bootstrap in its initialize() method.

So far, I've been able to achieve this by extending ConfiguredCommand in my Commands and creating DBI instances inside their run() methods, but this is a bad design, because dependencies should be injected into the object instead of creating them inside.

I'd prefer to inject DAOs or any other dependencies of my Commands through their constructor, but this seems currently impossible to me, as the Environment and the configuration are not accesible in Service initialization, when I need to create and add them to its bootstrap.

Does anyone know how to achieve this?

2条回答
唯我独甜
2楼-- · 2019-06-16 05:01

This is how I use Guice with Dropwizard. Inside your run() method add the line

Guice.createInjector(new ConsoleModule());

Create the class 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)
  }
}
查看更多
\"骚年 ilove
3楼-- · 2019-06-16 05:14

Can you use the EnvironmentCommand?

查看更多
登录 后发表回答