我有一个从数据库加载一些数据的@Singleton 类。Singleton 在引导期间加载,但是构造函数从 DAO 数据加载类中抛出异常。我从来没有看到这个异常,我假设是因为 Guice 的单例引导加载正在吞噬它。有没有更好的方法来做到这一点,以便我至少可以看到堆栈跟踪或异常消息?我希望不必对课程了解太多,但也许一旦我用@Singleton 标记了它,我应该知道在抛出异常之前记录它?
问问题
2024 次
1 回答
3
我建议不要让您的单身人士尝试在其构造函数中从数据库加载数据。一般来说,构造函数不应该工作。在构造函数中工作会使您的代码更难测试(因为在您调用对象上的任何方法之前,您需要构造它)。如果创建注入器,它也会减慢进程,并使注入器创建过程变得脆弱,因为依赖关系图中的细微变化会导致初始化以不同的顺序发生。
一种解决方案是使用Guava Service抽象。您在启动时需要做的任何工作都发生在服务中。服务绑定使用Multibinder.newSetBinder()
.
为此,您的 main 方法组装模块,创建主类,并在该主类上调用一个方法。您将在主类中注入一个ServiceManager ,然后入口方法启动服务。
这是一个例子
@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);
}
}
}
您可以通过创建一个扩展和添加方法的可重用ServiceModule
类来简化这一点。AbstractModule
bindService(Class<? extends Service>)
如果您愿意让您的单例类扩展AbstractIdleService
,您可以进一步简化这一点,但这会将Service
接口中的方法添加到您的单例的公共 API 中。
于 2015-03-02T00:20:02.920 回答