如何在guice中进行依赖I / O.

时间:2015-09-05 19:49:49

标签: java guice

Guice guidance on side-effects in modules基本上是"不做。"与执行I/O in Providers相同,我假设包含模块。然后,他们给出了一个使用Service接口的空白示例,该接口以正确的顺序启动其服务。

Injector injector = Guice.createInjector(
    new DatabaseModule(),
    new WebserverModule(),
    ...
);

Service databaseConnectionPool = injector.getInstance(
    Key.get(Service.class, DatabaseService.class));
databaseConnectionPool.start();
addShutdownHook(databaseConnectionPool);

Service webserver = injector.getInstance(
    Key.get(Service.class, WebserverService.class));
webserver.start();
addShutdownHook(webserver);

但在现实世界中,网络服务器传递依赖于数据库。而且,获得DataSource的唯一方法是连接到数据库。在Web服务器和数据库之间有几层抽象,都希望注入依赖项并开始服务。

我考虑过两种不同的选择来处理这种情况。首先是使用guice的服务,但注入Provider<DataSource>或等价物。但这会在我的代码中泄露,因为现在所有内容都使用Provider<LayerBelow>而不是实际的LayerBelow

我尝试的第二种方法是链接创建注入器,我在每层构建一个子注入器,启动该层,然后使用它为下一个创建子注入器。它似乎也很笨拙。像这样:

// I/O in the static method call; returns a module with
// the environment-based objects
EnvironmentModule environment = EnvironmentModule.configureEnvironment(args);

Injector injector = Guice.createInjector(
     environment,
     // the following connects to the database, and returns a module
     // providing the DataSource
     SQLModule.connectToDatabase());

injector = injector.createChildInjector(new BusinessLayerModule());
startTimers(injector);

injector = injector.createChildInjector(
    new ServicesModule(),
    new WebServerModule());

startServer(injector);

启动时是否有更好的方法来执行I / O和副作用?我使用的是Guice 4

相关问题:

2 个答案:

答案 0 :(得分:0)

我的方法类似于你的第二种方法,除了儿童注射器。

首先,创建一个专用于初始化的模块SQLModule:

Injector initInjector = Guice.createInjector(Stage.PRODUCTION, new SQLModule());
SQLService service = initInjector.getInstance(SQLService.class);
Properties initProps = service.doInit(); // for example

然后创建主模块:

Injector mainInjector = Guice.createInjector(Stage.PRODUCTION, 
                 new SQLModule(), 
                 new MainModule(initProps));
// main program here using the mainInjector

答案 1 :(得分:0)

例如,我有两个模块,主要用于整个应用程序&#34; fat&#34;非常早期注入,BasicConfigurationService非常早期注入;),Basic没有SQL连接等。目标是解析SQL连接和最常用的应用程序数据路径。

模块定义以这种方式设置,当main激活时,basic已经激活/注入。

对不起,如果我的英文不太清楚。