问题
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?
回答1:
Can you use the EnvironmentCommand?
回答2:
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)
}
}
来源:https://stackoverflow.com/questions/22319965/how-do-you-inject-jdbifactory-daos-into-a-dropwizard-command