Guice injector.getInstance() - 良好的做​​法?

alb*_*ano 14 java dependency-injection guice

假设我有两个应用程序共享同一个库.该库包含常见的类,如DAO,Utils等.共享库中的所有内容都与Guice连接.我的两个应用依赖于这个库,但没有直接依赖Guice.

 ______    ______    ______
|      |  |      |  |      |
| APP1 |->| LIB  |<-| APP2 |
'------'  '------'  '------'
Run Code Online (Sandbox Code Playgroud)

我目前使用这样的东西:

static <T> Utils.getInstanceOf (Class<T> type);
Run Code Online (Sandbox Code Playgroud)

这只是一个包装:

injector.getInstance (Class<T> type);
Run Code Online (Sandbox Code Playgroud)

但是guice文档说:

如果可行,请避免使用此方法,以便让Guice提前注入您的依赖项.

那么为两个应用程序提供依赖注入的最佳方法是什么,而不必在Guice模块中手动绑定它们?

Vla*_*eev 10

那么为两个应用程序提供依赖注入的最佳方法是什么,而不必在Guice模块中手动绑定它们?

没有这种方式.你要么完全拥抱Guice,要么不使用它并明确地传递你的依赖.好吧,以这种方式构造你的代码,所以你永远不会直接创建类依赖,通过构造函数传递它们,也可能被称为'依赖注入',但我敢肯定这不是你的意思.如果你不想在你的应用程序中使用Guice,那么你将无法获得比getInstance()丑陋更好的东西,尤其是因为你使用的是静态包装器.

理想情况下,您的库应该提供一个可以Guice.createInjector()在应用程序中安装的模块,或者相反,库应该提供一个Injector实例,您可以通过使用createChildInjector()和提供特定于应用程序的模块在应用程序中使用该实例.稍微修改此方法是将特定于应用程序的模块传递给库,以便将它们用于创建Injector.我最近在自定义类似servlet的界面上编写了基于Guice的API,使用最后一种方法完全不支持任何类型的DI,并且它工作正常.

在servlet或Jersey环境中使用Guice并不困难.例如,后者与Guice(至少在1.x版本中)具有开箱即用的集成.Guice servlet扩展也非常好用和方便.试试吧,亲眼看看吧.

  • @AlexB禁止不.我不是那个意思.我想我没有说清楚,可能犯了一个错误.我已经更新了答案. (2认同)

Mic*_*mlk 5

static <T> Utils.getInstanceOf (Class<T> type);

您最终得到的是一个Service Locator

虽然在一些小情况下,逃逸到其他创造对象中是可以接受的injector,但我不认为这是其中之一。您已经解决了服务定位器的所有缺点,并且可以通过使用您已经使用的工具来获得所有优点。


小智 5

如果您有一个方法需要在运行时创建类 C 的新实例,请将 Provider 绑定到您的类。C 将以通常的方式绑定,例如

public CModule extends AbstractModule {
    @Overide
    public void configure() {
        bind(C.class).to(CImpl.class);
    }
}
Run Code Online (Sandbox Code Playgroud)

创建 C 实例的类如下所示:

class UserOfC {
    private Provider<C> cProvider;
    ...

    @Inject
    UserOfC(Provider<C> cProvider, ...) {
        this.cProvider = cProvider;
        ...
    }

    public void doSomethingWithAC (...) {
        C myC = cProvider.get();  // not a singleton; new instance created!
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

Guice 免费支持 Provider 注入。如果 C 已绑定,您可以像注入 C 实例一样轻松地注入 Provider。

附加建议:

我强烈建议您在构建时注入所有依赖项(如果可能的话),即使它需要编写更多行代码。我已经使用 Guice 多年了,但还不需要部分构建或任何其他高级功能。

当我面临部分注入的需求时,我一般都是自己写工厂。我发现编写代码时更容易理解和调试。