Guice:为共享库创建注入器 [英] Guice: Creating Injectors for Shared Libs

查看:162
本文介绍了Guice:为共享库创建注入器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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 - 一个Swing应用程序

  • WidgetServer - 客户端将连接到/与之通信的小型EAR

  • WidgetShared - 包含客户端和服务器使用的公共类的commonsJAR

  • WidgetClient - a Swing app
  • WidgetServer - a small EAR that the client will connect to/communicate with
  • WidgetShared - a "commons" JAR that contains common classes used by both client and server

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

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);
}

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

The mySwingAppModule will define all the bindings for the Swing app's dependencies. I will do something very similar in the server EAR.

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

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 JAR调用 Guice.createInjector()

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.

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

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.

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

So, the code snippet above (Guice.createInjector(mySwingAppModule)) is actually not what my code will eventually look like (sorry I lied!).

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

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

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);

或者,像这样:

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?!?

提前致谢!

推荐答案

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();
}

这篇关于Guice:为共享库创建注入器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆