gpt4 book ai didi

dependency-injection - Dropwizard 和 Guice : injecting Environment

转载 作者:行者123 更新时间:2023-12-04 08:21:44 31 4
gpt4 key购买 nike

我目前正在构建一个基于 Dropwizard + Guice + Jersey 的应用程序,其中数据库访问暂时由 JDBI 处理。

我想要实现的是拥有典型的企业架构,其中资源访问服务类访问 DAO 类,该类又访问数据库。以适当的 DI 方式将所有这些连接起来会很好,尽管我想如果其他所有方法都失败了,我可以在应用程序的 run() 方法中构建我的对象图。

所以,我遇到了这里提到的这个问题 before :获取 DBIFactory 需要环境和配置,它们需要在 Guice 执行其注入(inject)魔法时而不是在 run() 时可用。

作为一个 Dropwizard 和 Guice 菜鸟,到目前为止,我设法整合的是我的 DAO 对象需要一个 Provider,这与

public class UserDAOProvider implements Provider<UserDAO> {

@Inject
Environment environment;
@Inject
Configuration configuration;

@Override
public UserDAO get() {
final DBIFactory factory = new DBIFactory();
final (MyConfiguration) config = (MyConfiguration) configuration;
DBI jdbi = null;
try {
jdbi = factory.build(environment, config.getDataSourceFactory(),
"mysql");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return jdbi.onDemand(UserDAO.class);
}

}

将其注册为单例提供程序应该让我将 UserDAO 注入(inject)我的服务中。

现在,我们如何真正将环境注入(inject)到 Provider 中?目前我被困在 Guice 提示没有为环境找到合适的构造函数,所以它试图实例化它而不是从 Dropwizard 本身获取它。

看起来这是可行的;有 dropwizard-guice我认为,它的 DropWizardEnvironmentModule 是我需要的包。但我觉得我只是在这里错过了一些难题,以了解如何将事物组合在一起。到目前为止,我还没有找到一个完整的工作示例......

最佳答案

我遇到了与 OP 相同的问题,但使用的是 Hibernate 而不是 JDBI。不过,我的简单解决方案适用于 JDBI - 只需切换 DBIFactory对于 SessionFactory .

首先在 Guice 模块中为单例 SessionFactory 添加注入(inject)提供程序:

public class MyModule extends AbstractModule {

private SessionFactory sessionFactory;

@Override
protected void configure() {
}

@Provides
SessionFactory providesSessionFactory() {

if (sessionFactory == null) {
throw new ProvisionException("The Hibernate session factory has not yet been set. This is likely caused by forgetting to call setSessionFactory during Application.run()");
}

return sessionFactory;
}

public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
}

您需要设置单例 SessionFactory从您的应用程序的 run() 方法。在您的情况下,使用 JDBI,您可以在此处创建和配置 DBIFactory,然后再将其交给 Guice 模块:
public void run(MyConfiguration configuration, Environment environment) {

myModule.setSessionFactory(hibernateBundle.getSessionFactory());
...
}

现在 SessionFactory 可以在任何需要的地方注入(inject)。我现在对我的 DAO 类使用隐式绑定(bind),只需使用 @Inject 注释构造函数并注入(inject) SessionFactory 单例。我没有明确地为 DAO 类创建提供程序:
@Singleton
public class WidgetDAO extends AbstractDAO<App> {

@Inject
public WidgetDAO(SessionFactory factory) {
super(factory);
}

public Optional<Widget> findById(Long id) {
return Optional.fromNullable(get(id));
}
...
}

现在我可以将我的 DAO 单例实例注入(inject)到资源中:
@Path("/widgets")
@Produces(MediaType.APPLICATION_JSON)
public class WidgetsResource {

private final WidgetDAO widgetDAO;

@Inject
public WidgetsResource(WidgetDAO widgetDAO) {
this.widgetDAO = widgetDAO;
}
...
}

请注意,此方法遵循仅注入(inject)直接依赖项的 Guice 建议。不要仅仅为了创建 DBI 工厂而尝试注入(inject) Envrionment 和 Configuration - 注入(inject)预构建的 DBI 工厂本身。

关于dependency-injection - Dropwizard 和 Guice : injecting Environment,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25581590/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com