当前位置: 首页 > 知识库问答 >
问题:

Dropwizard和Guice:注入环境

方博
2023-03-14

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

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

所以,我遇到了之前提到过的问题:获取DBIFactory需要环境和配置,它们需要在Guice执行注入魔法时可用,而不是在run()-time。

作为一个Dropwizard和Guice新手,到目前为止,我已经设法把我的DAO对象需要一个提供者放在一起,这是

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注入到我的服务中。

现在,我们实际上如何将环境注入到提供者中?目前,我一直在Guice抱怨没有找到适合环境的构造函数,所以它试图实例化它,而不是从Dropwizard本身获取它。

这似乎是可行的;有一个投递巫师-吉斯包,我认为它是我需要的。但我觉得我只是在这里错过了一些难题,以了解如何将事情放在一起。到目前为止,我还没有找到一个完整的工作示例...

共有3个答案

陆仲渊
2023-03-14

我们具有相同的配置(dw-jdbi-guice)和一个抽象的“基”应用程序类,这使事情变得更加复杂。

由于在<code>run</code>方法期间发生了许多事情,并且许多事情取决于配置对象,因此我们最终在run方法中创建了注入器。但是,由于我们还需要bootsrap中的对象(例如ObjectMapper),我们最终得到了一个列表

满言
2023-03-14

这就是我如何将Guice与Dropwizard一起使用。在您的run()方法中添加

Guice.createInjector(new ConsoleModule()); 

您不能注射环境

创建类ConsoleModule

public class ConsoleModule extends AbstractModule {

    //configuration and env variable declaration

    public  ConsoleModule(ConsoleConfiguration consoleConfig, Environment env)
    {
        this.consoleConfig = consoleConfig;
        this.env= env;
    }

    protected void configure()
    {
        //You should not inject Configuration and Environment in your provider since you are mixing     
        //dropwizard framework stuff with Guice.Neverthless you will have to bind them in the below order

        bind(Configuration.class).toInstance(consoleConfig.class);
        bind(Environment.class).toInstance(env.class);
        bind(UserDAO.class).toProvider(UserDAOProvider.class).in(Singleton.class);
    }
}
蓬森
2023-03-14

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

首先在 Guice 模块中为单例会话工厂添加注入提供程序:

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

您需要从应用程序的run()方法设置singleton<code>SessionFactory

public void run(MyConfiguration configuration, Environment environment) {

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

现在,会话工厂可以注入任何需要的地方。我现在对我的 DAO 类使用隐式绑定,只需使用 @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 单例实例注入资源:

@Path("/widgets")
@Produces(MediaType.APPLICATION_JSON)
public class WidgetsResource {

    private final WidgetDAO widgetDAO;

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

注意,这种方法遵循Guice推荐的只注入直接依赖项的方法。不要试图注入环境和配置,这样就可以创建一个DBI工厂——注入预先构建的DBI工厂本身。

 类似资料:
  • 我一直想利用Guice 但是,我开始遇到 Governator 和 Dropwizard 之间的类路径问题。我不得不在我的pom.xml中排除以下模块: 注意:我正在使用管理程序版本 1.3.3 但是现在我遇到的问题是没有指定基本包,乍一看是NoSuchMethodError,我想这可能是另一个类路径问题: 但是,在我的应用程序中,我使用了他们在dropwizer-guice github页面上显

  • 你好,我正在尝试使用dropwizard框架创建一个应用程序。我有DAO类impl,它需要一个连接管理器实例的句柄,然后用于获取数据库连接。我有一个多租户数据库应用程序。这个连接管理器将是一个自定义实现。 该应用程序使用hikari cp作为连接池和mysql数据库。我想使用dropwizard托管对象功能初始化数据源和连接池。一旦数据源被初始化,我想使用guice绑定在每个dao类中注入连接管理

  • 我正在使用Guice和Dropwizard开发一个应用程序,在其中我们创建了不同的包,如Guice包、migrations包等,并将它们添加到initialize()方法中的bootstrap中。 注意:我知道另一种方法,您可以在run()方法中创建Module类的对象,用于创建注入器(配置和环境对象在MyModule类的构造函数中作为参数传递)。但这需要我在run()方法中注册所有托管对象和所有

  • 这是我的gradle档案: 在添加了Atmospher-Jursey之后,我得到了以下错误:

  • 我正在使用 scala play 2.5,在尝试在我的一个控制器中注入对象时出现以下错误。我正在使用 play 给出的默认注入框架,即 Guice。 这是控制器: 以下是我想注入的服务: 这就是我使用它的方式:

  • 主要内容:Google Guice 按需注入 示例,输出注入是将依赖注入对象的过程。方法和字段注入可用于使用injector.injectMembers()方法使用退出对象进行初始化。请参阅下面的示例。 Google Guice 按需注入 示例 创建一个名为 GuiceTester 的 Java 类。 GuiceTester.java 输出 编译并运行该文件,您将看到以下输出。