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
库时,我感到窒息,因为该库没有单一的入口点:它只是客户端和服务器将要访问的一堆包、类、接口和枚举。到处使用。
所以我的第一个问题:在哪里为 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);
这两个看起来真的很恶心!有更好的方法来实现这个吗?!?
提前致谢!
New to Google Guice. I'd like to use it to handle all IoC and AOP method interception for three components I am developing:
WidgetClient
- a Swing appWidgetServer
- a small EAR that the client will connect to/communicate withWidgetShared
- a "commons" JAR that contains common classes used by both client and server
With the Swing app, somewhere I'll make an explicit call that might look like:
public static void main(String[] args) {
initGuiceInjectors();
}
private static initGuiceInjectors() {
Guice.createInjector(mySwingAppModule);
}
The mySwingAppModule
will define all the bindings for the Swing app's dependencies. I will do something very similar in the server EAR.
When it comes to the WidgetShared
library, I'm choking, because the lib doesn't have a single entry point: it's just a bunch of packages, classes, interfaces and enums that the client and server will use all over the place.
So my first question: where do I invoke Guice.createInjector()
for the WidgetShared
JAR?
This question underscores a segue into a second (similar) question, which is why I chose to group it here as well.
I read up on Guice's "best practices", and the overwhelming consensus seems to be to (where applicable), keep Module
implementations at the package level. Thus for every package, there will be one Module
concretion defining bindings for all types within that package. This is an improvement over a single monolithic Module
defining bindings for the entire app.
So, the code snippet above (Guice.createInjector(mySwingAppModule)
) is actually not what my code will eventually look like (sorry I lied!).
My second question is: what are the "best practices" for creating multiple injectors?
I see that createInjector(Module... modules)
can take vararg Module
arguments. So, to me it seems like if I want to embrace this "1-module-per-package" best practice, at some point I have to have code that either looks like this:
Guice.creatorInjector(package1Module, package2Module, package3Module,
package4Module, package5Module, package6Module, ..., packageNModule);
or, like this:
Guice.createInjector(package1Module);
Guice.createInjector(package2Module);
Guice.createInjector(package3Module);
...
Guice.createInjector(packageNModule);
Both of these look really nasty! Is there a better way to accomplish this?!?
Thanks in advance!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
亚当,
你的问题有两个要素,但显然两者都是相关的。我将倒退,首先从第二个元素开始。
每个包一个模块的组织很重要,因为它给出了绑定应该放置在哪里的可预测约定,并且作为奖励,它允许您相应地打包保护您的类。还有一种流行的概念是创建复合模块,这些模块主要用于安装每个包模块的集合,以便充当需要安装的单个模块来为库的给定配置添加绑定。安装这个单一模块成为库和使用它的服务器/应用程序之间的主要集成点。
回到第一点,不建议每个应用程序有多个注射器。更好的是让单个注入器安装满足应用程序中使用的所有绑定所需的模块。
最后,你会得到类似的东西:
你的主要方法将如下所示:
Adam,
There are two elements to your question, but clearly both related. I'll go backwards, starting with the second element first.
The organization of one module per package is important because it gives a predictable convention of where bindings should be placed, and as a bonus, it allows you to package protect your classes accordingly. There is also the popular notion of creating composite modules that act primarily to install a collection of per-package modules in order to act as the single module that needs to be installed to add bindings for a given configuration of a library. Installing this single module becomes the main integration point between the library and the server/application that uses it.
Bouncing back to your first point, it's not recommended to have multiple injectors per application. What is better is to have a single injector install the modules that it needs to satisfy all bindings used in the app.
In the end, you'd have something like:
And your main method would look like: