Guice单例和构造函数异常

Guice单例和构造函数异常,guice,guice-3,Guice,Guice 3,我有一个@Singleton类,它从数据库加载一些数据。单例在引导过程中加载,但是构造函数从DAO数据加载类抛出异常。我从来没有看到过这种异常,因为Guice的单例引导加载正在吞噬它。有没有更好的方法来做到这一点,这样我至少可以看到堆栈跟踪或异常消息?我希望不必对该类了解太多,但是一旦我用@Singleton标记它,我应该知道在抛出异常之前记录异常?我建议不要让你的Singleton尝试从它的构造函数中的数据库加载数据。一般来说,施工人员不应该做任何工作。在构造函数中工作会使代码更难测试(因为在

我有一个@Singleton类,它从数据库加载一些数据。单例在引导过程中加载,但是构造函数从DAO数据加载类抛出异常。我从来没有看到过这种异常,因为Guice的单例引导加载正在吞噬它。有没有更好的方法来做到这一点,这样我至少可以看到堆栈跟踪或异常消息?我希望不必对该类了解太多,但是一旦我用@Singleton标记它,我应该知道在抛出异常之前记录异常?

我建议不要让你的Singleton尝试从它的构造函数中的数据库加载数据。一般来说,施工人员不应该做任何工作。在构造函数中工作会使代码更难测试(因为在调用对象上的任何方法之前,您需要构造它)。如果创建一个注入器,它也会减慢这个过程,并使注入器创建过程变得脆弱,因为依赖关系图中的细微变化会导致初始化以不同的顺序发生

一种解决方案是使用抽象。启动时需要做的任何工作都发生在服务中。使用
Multibinder.newSetBinder()
绑定服务

为此,main方法组装模块,创建主类,并对该主类调用一个方法。您将向主类中注入,entry方法启动服务

这里有一个例子

@Singleton
public class MySingleton {
  private final FooDao dao;
  private final List<Foo> foos = new ArrayList<>();

  @Inject
  MySingleton(FooDao dao) {
    this.dao = dao;
  }

  @VisibleForTesting
  void initialize() {
    foos.addAll(dao.getAllFoos());
  }

  private static class StartupService extends AbstractIdleService {
    private final MySingleton singleton;

    @Inject
    StartupService(MySingleton singleton) {
      this.singleton = singleton;
    }

    @Override protected void startUp() {
      singleton.initialize();
    }
  }

  public static class Module extends AbstractModule {

    @Override protected void configure() {
      Multibinder.newSetBinder(binder(), Service.class)
          .addBinding().to(StartupService.class);
    }
  }
}
@Singleton
公共课米辛格尔顿{
私人最终食物刀;
私有最终列表foos=newarraylist();
@注入
米辛格尔顿(食物岛){
this.dao=dao;
}
@可视性测试
void initialize(){
addAll(dao.getAllFoos());
}
私有静态类StartupService扩展了AbstractIdleService{
私人决赛迈辛格尔顿单打;
@注入
StartupService(MySingleton singleton){
this.singleton=singleton;
}
@覆盖受保护的无效启动(){
singleton.initialize();
}
}
公共静态类模块扩展了AbstractModule{
@覆盖受保护的void configure(){
Multibinder.newSetBinder(binder(),Service.class)
.addBinding().to(StartupService.class);
}
}
}

您可以通过创建可重用的
ServiceModule
类来简化此过程,该类扩展了
AbstractModule
,并添加了
bindService(Class我建议不要让你的单例从数据库的构造函数中加载数据。一般来说,构造函数不应该工作。在构造函数中工作会使你的代码更难测试(因为在调用对象上的任何方法之前,你需要构造它)。如果创建注入器,它还会减慢过程,并使注入器创建过程变得脆弱,因为依赖关系图中的细微更改会导致初始化以不同的顺序进行

一种解决方案是使用抽象。启动时需要做的任何工作都发生在服务中。这些服务使用
Multibinder.newSetBinder()
绑定

为此,主方法组装模块,创建主类,并调用该主类上的一个方法

这里有一个例子

@Singleton
public class MySingleton {
  private final FooDao dao;
  private final List<Foo> foos = new ArrayList<>();

  @Inject
  MySingleton(FooDao dao) {
    this.dao = dao;
  }

  @VisibleForTesting
  void initialize() {
    foos.addAll(dao.getAllFoos());
  }

  private static class StartupService extends AbstractIdleService {
    private final MySingleton singleton;

    @Inject
    StartupService(MySingleton singleton) {
      this.singleton = singleton;
    }

    @Override protected void startUp() {
      singleton.initialize();
    }
  }

  public static class Module extends AbstractModule {

    @Override protected void configure() {
      Multibinder.newSetBinder(binder(), Service.class)
          .addBinding().to(StartupService.class);
    }
  }
}
@Singleton
公共课米辛格尔顿{
私人最终食物刀;
私有最终列表foos=newarraylist();
@注入
米辛格尔顿(食物岛){
this.dao=dao;
}
@可视性测试
void initialize(){
addAll(dao.getAllFoos());
}
私有静态类StartupService扩展了AbstractIdleService{
私人决赛迈辛格尔顿单打;
@注入
StartupService(MySingleton singleton){
this.singleton=singleton;
}
@覆盖受保护的无效启动(){
singleton.initialize();
}
}
公共静态类模块扩展了AbstractModule{
@覆盖受保护的void configure(){
Multibinder.newSetBinder(binder(),Service.class)
.addBinding().to(StartupService.class);
}
}
}

您可以通过创建可重用的
ServiceModule
类来简化此过程,该类扩展了
AbstractModule
,并添加了
bindService(Class我建议不要让你的单例从数据库的构造函数中加载数据。一般来说,构造函数不应该工作。在构造函数中工作会使你的代码更难测试(因为在调用对象上的任何方法之前,你需要构造它)。如果创建注入器,它还会减慢过程,并使注入器创建过程变得脆弱,因为依赖关系图中的细微更改会导致初始化以不同的顺序进行

一种解决方案是使用抽象。启动时需要做的任何工作都发生在服务中。这些服务使用
Multibinder.newSetBinder()
绑定

为此,主方法组装模块,创建主类,并调用该主类上的一个方法

这里有一个例子

@Singleton
public class MySingleton {
  private final FooDao dao;
  private final List<Foo> foos = new ArrayList<>();

  @Inject
  MySingleton(FooDao dao) {
    this.dao = dao;
  }

  @VisibleForTesting
  void initialize() {
    foos.addAll(dao.getAllFoos());
  }

  private static class StartupService extends AbstractIdleService {
    private final MySingleton singleton;

    @Inject
    StartupService(MySingleton singleton) {
      this.singleton = singleton;
    }

    @Override protected void startUp() {
      singleton.initialize();
    }
  }

  public static class Module extends AbstractModule {

    @Override protected void configure() {
      Multibinder.newSetBinder(binder(), Service.class)
          .addBinding().to(StartupService.class);
    }
  }
}
@Singleton
公共课米辛格尔顿{
私人最终食物刀;
私有最终列表foos=newarraylist();
@注入
米辛格尔顿(食物岛){
this.dao=dao;
}
@可视性测试
void initialize(){
addAll(dao.getAllFoos());
}
私有静态类StartupService扩展了AbstractIdleService{
私人决赛迈辛格尔顿单打;
@注入
StartupService(MySingleton singleton){
this.singleton=singleton;
}
@覆盖受保护的无效启动(){
singleton.initialize();
}
}
公共静态类模块扩展了AbstractModule{
@覆盖受保护的void configure(){
Multibinder.newSetBinder(binder(),Service.class)
.addBinding().to(StartupService.class);
}
}
}
您可以通过创建可重用的
ServiceModule
类来简化此过程,该类扩展