Dropwizard and Guice: injecting Environment

前端 未结 3 2041
隐瞒了意图╮
隐瞒了意图╮ 2021-02-15 17:53

I am currently building a Dropwizard + Guice + Jersey-based application where the database access is being handled by JDBI for the time being.

What I am trying to achiev

3条回答
  •  -上瘾入骨i
    2021-02-15 18:18

    I had the same issue as OP but using Hibernate rather than JDBI. My simple solution is applicable to JDBI, though - just switch DBIFactory for SessionFactory.

    First add an injection provider for a singleton SessionFactory in your Guice module:

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

    You need to set the singleton SessionFactory from your application's run() method. In your case, using JDBI, this is where you would create and configure your DBIFactory before handing it over to the Guice module:

    public void run(MyConfiguration configuration, Environment environment) {
    
        myModule.setSessionFactory(hibernateBundle.getSessionFactory());
        ...
    }
    

    Now SessionFactory can be injected wherever it is needed. I now use implicit binding for my DAO classes by just annotating the constructor with @Inject and injecting the SessionFactory singleton. I don't explicitly create providers for DAO classes:

    @Singleton
    public class WidgetDAO extends AbstractDAO {
    
        @Inject
        public WidgetDAO(SessionFactory factory) {
            super(factory);
        }
    
        public Optional findById(Long id) {
            return Optional.fromNullable(get(id));
        }
        ...
    }
    

    Now I can inject my DAO singleton instances into resources:

    @Path("/widgets")
    @Produces(MediaType.APPLICATION_JSON)
    public class WidgetsResource {
    
        private final WidgetDAO widgetDAO;
    
        @Inject
        public WidgetsResource(WidgetDAO widgetDAO) {
            this.widgetDAO = widgetDAO;
        }
        ...
    }
    

    Note that this approach follows the Guice recommendation of injecting direct dependencies only. Don't try to inject Envrionment and Configuration just so that you can create a DBI factory - inject the prebuilt DBI factory itself.

提交回复
热议问题