Guice:为共享库创建注入器

Google Guice新手。 我想用它来处理我正在开发的三个组件的所有IoC和AOP方法拦截:

  • WidgetClient – 一个Swing应用程序
  • WidgetServer – 客户端将连接到/与之通信的小型EAR
  • WidgetShared – 一个“commons”JAR,包含客户端和服务器使用的公共类

使用Swing应用程序,我会在某个地方进行显式调用,如下所示:

 public static void main(String[] args) { initGuiceInjectors(); } private static initGuiceInjectors() { Guice.createInjector(mySwingAppModule); } 

mySwingAppModule将定义Swing应用程序依赖项的所有绑定。 我将在服务器EAR中做一些非常相似的事情。

当谈到WidgetShared库时,我很窒息,因为lib没有一个入口点:它只是客户端和服务器将在整个地方使用的一堆包,类,接口和枚举。

所以我的第一个问题是: 我在哪里为WidgetShared JAR调用Guice.createInjector()

这个问题强调了第二个(类似的)问题,这也是我选择在这里进行分组的原因。

我阅读了Guice的“最佳实践”,并且压倒性的共识似乎是(在适用的情况下),将Module实现保持在包级别。 因此,对于每个包,将有一个Module具体化定义该包中所有类型的绑定。 这是对单个整体Module的改进,它定义了整个应用程序的绑定。

所以,上面的代码片段( Guice.createInjector(mySwingAppModule) )实际上并不是我的代码最终会是什么样的(抱歉我撒了!)。

我的第二个问题是: 创建多个注射器的“最佳实践”什么?

我看到createInjector(Module... modules)可以使用vararg Module参数。 所以,对我而言,似乎我想拥抱这个“ 每个模块1个模块 ”的最佳实践,在某些时候我必须拥有如下所示的代码:

 Guice.creatorInjector(package1Module, package2Module, package3Module, package4Module, package5Module, package6Module, ..., packageNModule); 

或者,像这样:

 Guice.createInjector(package1Module); Guice.createInjector(package2Module); Guice.createInjector(package3Module); ... Guice.createInjector(packageNModule); 

这两个看起来都很讨厌! 有没有更好的方法来实现这一目标?!?

提前致谢!

亚当,

你的问题有两个要素,但显然都是相关的。 我会倒退,先从第二个元素开始。

每个程序包组织一个模块很重要,因为它提供了一个可预测的约束应该放置的约定,作为奖励,它允许您相应地打包保护您的类。 还有一种流行的概念,即创建复合模块,主要用于安装每个包模块的集合,以便充当需要安装的单个模块,以便为库的给定配置添加绑定。 安装此单个模块成为库与使用它的服务器/应用程序之间的主要集成点。

回到第一点,不建议每个应用程序有多个喷射器。 更好的方法是让一个注入器安装它所需的模块,以满足应用程序中使用的所有绑定。

最后,你会有类似的东西:

 public WidgetSharedLibraryModule extends AbstractModule { @Override protected void configure() { install(new WidgetSublibraryModule1()); install(new WidgetSublibraryModule2()); ... } } 

你的主要方法如下:

 public static void main(String[] args) { Injector injector = Guice.createInjector( new WidgetSharedLibrary(), new WidgetSwingAppModule()); WidgetSwingApp app = injector.getInstance(WidgetSwingApp.class); app.run(); }