Java 如何使用dropwizard上的guice自动连接HibernateBundle?

Java 如何使用dropwizard上的guice自动连接HibernateBundle?,java,hibernate,guice,dropwizard,Java,Hibernate,Guice,Dropwizard,我正在尝试使用guice/dropwizard配置hibernatebundle,需要帮助。 除了dropwizard库之外,我还使用第三方库 下面的代码显然不起作用,需要帮助解决。我如何重写它,使hibernatebundle和最终的会话工厂自动注入到任何需要它的bean中 MyApplication.java public class MyApplication extends Application<MyAppConfiguration> { private fina

我正在尝试使用guice/dropwizard配置hibernatebundle,需要帮助。 除了dropwizard库之外,我还使用第三方库

下面的代码显然不起作用,需要帮助解决。我如何重写它,使hibernatebundle和最终的会话工厂自动注入到任何需要它的bean中

MyApplication.java

public class MyApplication extends Application<MyAppConfiguration> {

    private final HibernateBundle<MyAppConfiguration> hibernateBundle = new HibernateBundle<MyAppConfiguration>(MyModel.class) {
        @Override
        public DataSourceFactory getDataSourceFactory(MyAppConfiguration configuration) {
            return configuration.getDataSourceFactory();
        }
    };

    @Override
    public void initialize(Bootstrap<MyAppConfiguration> bootstrap) {
        bootstrap.addBundle(hibernateBundle);  // ???

        bootstrap.addBundle(
            GuiceBundle.<MyAppConfiguration>newBuilder()
                    .addModule(new MyAppModule())
                    .enableAutoConfig(getClass().getPackage().getName())
                    .setConfigClass(MyAppConfiguration.class)
                    .build()
        );
    }

}   
public class MyAppConfiguration extends Configuration {
    @Valid
    @NotNull
    private DataSourceFactory database = new DataSourceFactory();

    @JsonProperty("database")
    public DataSourceFactory getDataSourceFactory() {
        return database;
    }

    @JsonProperty("database")
    public void setDataSourceFactory(DataSourceFactory dataSourceFactory) {
        this.database = dataSourceFactory;
    }

        // ???
    public HibernateBundle<MyAppConfiguration> getHibernateBundle() {
        return new HibernateBundle<MyAppConfiguration>(MyModel.class) {
            @Override
            public DataSourceFactory getDataSourceFactory(MyAppConfiguration configuration) {
                return database;
            }
        };
    }

}  
MyAppConfiguration.java

public class MyApplication extends Application<MyAppConfiguration> {

    private final HibernateBundle<MyAppConfiguration> hibernateBundle = new HibernateBundle<MyAppConfiguration>(MyModel.class) {
        @Override
        public DataSourceFactory getDataSourceFactory(MyAppConfiguration configuration) {
            return configuration.getDataSourceFactory();
        }
    };

    @Override
    public void initialize(Bootstrap<MyAppConfiguration> bootstrap) {
        bootstrap.addBundle(hibernateBundle);  // ???

        bootstrap.addBundle(
            GuiceBundle.<MyAppConfiguration>newBuilder()
                    .addModule(new MyAppModule())
                    .enableAutoConfig(getClass().getPackage().getName())
                    .setConfigClass(MyAppConfiguration.class)
                    .build()
        );
    }

}   
public class MyAppConfiguration extends Configuration {
    @Valid
    @NotNull
    private DataSourceFactory database = new DataSourceFactory();

    @JsonProperty("database")
    public DataSourceFactory getDataSourceFactory() {
        return database;
    }

    @JsonProperty("database")
    public void setDataSourceFactory(DataSourceFactory dataSourceFactory) {
        this.database = dataSourceFactory;
    }

        // ???
    public HibernateBundle<MyAppConfiguration> getHibernateBundle() {
        return new HibernateBundle<MyAppConfiguration>(MyModel.class) {
            @Override
            public DataSourceFactory getDataSourceFactory(MyAppConfiguration configuration) {
                return database;
            }
        };
    }

}  
公共类MyAppConfiguration扩展了配置{
@有效的
@NotNull
私有DataSourceFactory数据库=新DataSourceFactory();
@JsonProperty(“数据库”)
公共数据源工厂getDataSourceFactory(){
返回数据库;
}
@JsonProperty(“数据库”)
public void setDataSourceFactory(DataSourceFactory DataSourceFactory){
this.database=dataSourceFactory;
}
// ???
公共HibernateBundle getHibernateBundle(){
返回新的HibernateBundle(MyModel.class){
@凌驾
公共数据源工厂getDataSourceFactory(MyAppConfiguration配置){
返回数据库;
}
};
}
}  

我没有在dropwizard中使用hibernate,但我使用了Guice,您只需要担心MyAppModule。这就是魔法发生的地方:

public class MyAppModule extends AbstractModule {

    @Singleton
    @Provides
    public SessionFactory provideSessionFactory(MyAppConfiguration configuration) {
        HibernateBundle<MyAppConfiguration> hibernate = new HibernateBundle<ExampleConfiguration>(MyModel.class) {
            @Override
            public DataSourceFactory getDataSourceFactory(MyAppConfiguration configuration) {
                return configuration.getDataSourceFactory();
            }
        }

        return hibernate.getSessionFactory();
    }
}
公共类MyAppModule扩展了AbstractModule{
@独生子女
@提供
公共会话工厂提供会话工厂(MyAppConfiguration配置){
HibernateBundle hibernate=新的HibernateBundle(MyModel.class){
@凌驾
公共数据源工厂getDataSourceFactory(MyAppConfiguration配置){
返回配置。getDataSourceFactory();
}
}
返回hibernate.getSessionFactory();
}
}
(有关多个类,请参见)


MyAppConfiguration.java和MyApplication.java中不应有任何hibernate捆绑包引用。然后,您应该能够在任何需要的地方@injection SessionFactory。

下面是我最终的做法。我从来没有从这里或邮寄名单得到答复,所以我会认为这个黑客和可能不是正确的方式来做它,但它对我工作。 在我的模块(扩展了abstractmodule)中:

我认为显式运行(配置、环境)调用(在@StephenNYC提供的答案中)有点奇怪,所以有点深入。我发现dropwizard GUI中的自动配置没有正确设置ConfiguredBundle(HibernateBundle就是这样一种类型)

到目前为止,代码可以改为如下所示:

@Singleton
public class MyHibernateBundle extends HibernateBundle<NoxboxConfiguration> implements ConfiguredBundle<MyConfiguration>
{
    public MyHibernateBundle()
    {
        super(myDbEntities(), new SessionFactoryFactory());
    }

    private static ImmutableList<Class<?>> myDbEntities()
    {
        Reflections reflections = new Reflections("com.acme");
        ImmutableList<Class<?>> entities = ImmutableList.copyOf(reflections.getTypesAnnotatedWith(Entity.class));
        return entities;
    }

    @Override
    public DataSourceFactory getDataSourceFactory(NoxboxConfiguration configuration)
    {
        return configuration.getMyDb();
    }
}

@Provides
public SessionFactory sessionFactory(MyHibernateBundle hibernate)
{
    return checkNotNull(hibernate.getSessionFactory());
}
@Singleton
公共类MyHibernateBundle扩展了HibernateBundle实现了ConfiguredBundle
{
公共MyHibernateBundle()
{
super(myDbEntities(),new SessionFactoryFactory());
}
私有静态ImmutableList>entities=ImmutableList.copyOf(reflections.getTypesAnnotatedWith(Entity.class));
返回实体;
}
@凌驾
公共数据源工厂getDataSourceFactory(NoxboxConfiguration配置)
{
返回configuration.getMyDb();
}
}
@提供
公共会话工厂会话工厂(MyHibernateBundle hibernate)
{
返回checkNotNull(hibernate.getSessionFactory());
}

这背后的神奇之处在于MyHibernateBundle实现了ConfiguredBundle,dropwizard guice现在会自动拾取并实例化它。

以下是我解决它的方法:
将Hibernate捆绑包放在guice模块中,并将bootstap对象作为guice模块构造函数的参数传递,以便将Hibernate捆绑包添加到其中。
配置可以保持与不使用GUI的hibernate捆绑包完全相同。
我使用dropwizard hibernate v0.7.1和dropwizard guice v0.7.0.3实现了这一点

MyAppModule.java:


你修好了吗?我也有同样的问题。这在dropwizard guice 0.7.2和dropwizard hibernate 0.7.1中不适用。SessionFactory返回为null奇怪,我得到了一个使用这些版本的示例。有关示例,请参见[链接]()。空值可能与您尝试执行@Inject的位置有关。dropwizard guice模块并没有注入所有类。@Sathish在构建guice捆绑包时,您需要将build stage设置为stage.DEVELOPMENT。否则,即使在初始化hibernate捆绑包之前,guice也会尝试初始化获取会话工厂。嗯,我得到“没有绑定org.hibernate.SessionFactory的实现”。缺少信息:此代码必须插入到模块类中。MyHibernateBundle类定义中还缺少静态修饰符。在它真正起作用之后,甚至比其他答案更好。一些更完整的信息会更好。Guice模块和HibernateBundle之间的关系不清楚。@roded是在dropwizard Guice 0.8.0中发布的。guice和HibernateBundle之间的链接使用ConfiguredBundle接口。dropwizard GUI扫描接口,并获取实现接口的所有类并实例化它们由于模块中没有可用的
环境
实例(扩展了abstractmodule)?
@Singleton
public class MyHibernateBundle extends HibernateBundle<NoxboxConfiguration> implements ConfiguredBundle<MyConfiguration>
{
    public MyHibernateBundle()
    {
        super(myDbEntities(), new SessionFactoryFactory());
    }

    private static ImmutableList<Class<?>> myDbEntities()
    {
        Reflections reflections = new Reflections("com.acme");
        ImmutableList<Class<?>> entities = ImmutableList.copyOf(reflections.getTypesAnnotatedWith(Entity.class));
        return entities;
    }

    @Override
    public DataSourceFactory getDataSourceFactory(NoxboxConfiguration configuration)
    {
        return configuration.getMyDb();
    }
}

@Provides
public SessionFactory sessionFactory(MyHibernateBundle hibernate)
{
    return checkNotNull(hibernate.getSessionFactory());
}
public class MyAppModule extends AbstractModule {
  private final HibernateBundle<MyAppConfiguration> hibernateBundle = new HibernateBundle<MyAppConfiguration>(MyModel.class) {
    @Override
    public DataSourceFactory getDataSourceFactory(MyAppConfiguration configuration) {
        return configuration.getDataSourceFactory();
    }
  };

  public MyAppModule(Bootstrap<MyAppConfiguration> bootstrap) {
    bootstrap.addBundle(hibernateBundle);
  }

  @Override
  protected void configure() {
  }

  @Provides
  public SessionFactory provideSessionFactory() {
    return hibernateBundle.getSessionFactory();
  }
}
public class MyApplication extends Application<MyAppConfiguration> {

  @Override
  public void initialize(Bootstrap<MyAppConfiguration> bootstrap) {
    bootstrap.addBundle(
            GuiceBundle.<MyAppConfiguration>newBuilder()
                    .addModule(new MyAppModule(bootstrap))
                    .enableAutoConfig(getClass().getPackage().getName())
                    .setConfigClass(MyAppConfiguration.class)
                    .build()
    );
  }

  @Override
  public void run(final MyAppConfiguration configuration, final Environment environment) throws Exception {
  }

}  
public class MyAppConfiguration extends Configuration {
  @Valid
  @NotNull
  @JsonProperty("database")
  private DataSourceFactory database = new DataSourceFactory();

  public DataSourceFactory getDataSourceFactory() {
    return database;
  }
}