简体   繁体   English

Guice:为共享库创建注入器

[英]Guice: Creating Injectors for Shared Libs

New to Google Guice. Google Guice新手。 I'd like to use it to handle all IoC and AOP method interception for three components I am developing: 我想用它来处理我正在开发的三个组件的所有IoC和AOP方法拦截:

  • WidgetClient - a Swing app WidgetClient - 一个Swing应用程序
  • WidgetServer - a small EAR that the client will connect to/communicate with WidgetServer - 客户端将连接到/与之通信的小型EAR
  • WidgetShared - a "commons" JAR that contains common classes used by both client and server WidgetShared - 一个“commons”JAR,包含客户端和服务器使用的公共类

With the Swing app, somewhere I'll make an explicit call that might look like: 使用Swing应用程序,我会在某个地方进行显式调用,如下所示:

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. mySwingAppModule将定义Swing应用程序依赖项的所有绑定。 I will do something very similar in the server EAR. 我将在服务器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. 当谈到WidgetShared库时,我很窒息,因为lib没有一个入口点:它只是客户端和服务器将在整个地方使用的一堆包,类,接口和枚举。

So my first question: where do I invoke Guice.createInjector() for the WidgetShared JAR? 所以我的第一个问题是: 我在哪里为WidgetShared JAR调用Guice.createInjector()

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. 我阅读了Guice的“最佳实践”,并且压倒性的共识似乎是(在适用的情况下),将Module实现保持在包级别。 Thus for every package, there will be one Module concretion defining bindings for all types within that package. 因此,对于每个包,将有一个Module具体定义该包中所有类型的绑定。 This is an improvement over a single monolithic Module defining bindings for the entire app. 这是对单个整体Module的改进,它定义了整个应用程序的绑定。

So, the code snippet above ( Guice.createInjector(mySwingAppModule) ) is actually not what my code will eventually look like (sorry I lied!). 所以,上面的代码片段( Guice.createInjector(mySwingAppModule) )实际上不是我的代码最终会是什么样的(对不起,我撒了!)。

My second question is: what are the "best practices" for creating multiple injectors? 我的第二个问题是: 创建多个注射器的“最佳实践”什么?

I see that createInjector(Module... modules) can take vararg Module arguments. 我看到createInjector(Module... modules)可以使用vararg Module参数。 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: 所以,对我而言,似乎我想拥抱这个“ 每个模块1个模块 ”的最佳实践,在某些时候我必须拥有如下所示的代码:

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! 提前致谢!

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: 最后,你会有类似的东西:

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

And your main method would look like: 你的主要方法如下:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM