我开始与Dropwizard工作,我试图创建一个需要使用数据库的命令。如果有人想知道我为什么要这样做,我可以提供很好的理由,但这不是我问题的重点。它是关于依赖倒置,服务初始化和运行阶段的Dropwizard。
Dropwizard鼓励使用它的dbfactory来构建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()
方法中将命令添加到服务的引导中。
run()
方法中创建DBI
实例来实现这一点,但这是一个糟糕的设计,因为依赖关系应该注入到对象中,而不是在内部创建它们。我更愿意通过它们的构造函数注入dao或我的命令的任何其他依赖项,但这对我来说目前似乎是不可能的,因为Environment
和配置在服务初始化中不可访问,当我需要创建并添加它们到其引导时。
有人知道如何实现这一点吗?
您会使用环境命令吗?
这是我如何使用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)
}
}