【问题标题】:Guice: Do injections require bindings or interfaces? Do we need to get an instance of the injector?Guice:注入是否需要绑定或接口?我们需要获取注入器的实例吗?
【发布时间】:2021-05-08 16:12:22
【问题描述】:

我对绑定如何与 Guice 一起工作感到很困惑。我是一家公司的初级开发人员,我正在查看我们的代码库,试图了解我们如何在我们的应用程序中实现 Guice。

我正在阅读有关 Guice 注入的指南:https://www.tutorialspoint.com/guice/guice_first_application.htm,它看起来就像我们在我公司的做法。

  1. 第一步说创建接口。我们确实在 Module 类中有一个扩展 AbstractModule 的绑定。

例如: bind(SampleManager.class).to(SampleManagerImpl.class).in(Singleton.class)

我们确实在代码库中的这个 SampleManager 类上使用了 @Inject

  1. 指南中的第 5 步和第 6 步说创建一个注入器并获取它的一个实例。我们在我们的应用程序中根本不这样做。它是如何工作的?

  2. 我们有很多类的实例被注入,它们根本没有被绑定,而是用单例注释。例如,我们有 TestManager 附加了 Guice 注释 @Singleton。然后我们将它注入到其他类中。

所以这给我留下了以下问题:

  • 是否需要绑定?
  • 使用注入和单例有区别吗?
  • 接口SampleManager 有一个方法,并且没有被任何其他类实现。为什么还要使用接口?拥有一个由 one 类实现的接口对我来说毫无意义。它看起来臃肿而混乱。
  • 为什么我们不需要执行第 5 步和第 6 步?为什么我们不需要获取注入器的实例?

【问题讨论】:

    标签: java dependency-injection guice inject


    【解决方案1】:

    绑定还有必要吗?

    是的,绑定注册了 Guice 将尝试注入的对象。没有它们,Guice 不知道您要什么。 Guice 有点像 Map,其中 Class 是 Key(或者可选的 Key 类),实例化的对象是 value。

    对于您看不到与bind() 绑定的对象,它们可能通过带有@Provides 注释的方法提供,这与bind() 非常相似,但允许您在实例化期间运行一些代码。

    使用注入和单例有区别吗?

    @Inject 基本上告诉 Guice '在这里注入东西'。您希望 Guice 将参数注入的任何方法都需要它。它还可以标记在对象实例化时注入的类级别变量。

    @Singleton 是 Guice 在注入期间如何实例化对象的修饰符。如果没有@Singleton,Guice 每次注入一个新对象时都会创建一个新对象。使用@Singleton,Guice 创建一次对象,然后在每次请求绑定时注入相同的实例。您可以阅读有关 Guice 范围的信息 here

    SampleManager 接口只有一个方法,不会被任何其他类实现。为什么还要使用接口?拥有一个由一个类实现的接口对我来说毫无意义。它看起来臃肿而混乱。

    在不了解代码库的情况下无法确定,但这是一种非常常见的模式。如果您想在将来将其替换为具有不同实现的新类,可能只会使重构变得更容易。

    为什么我们不需要执行第 5 步和第 6 步?为什么我们不需要获取注入器的实例?

    注入器用于获取需要使用 Guice 创建的对象的实例,当您不能让 Guice 为您注入值时。就像如果你想要一个 SampleManager 的实例,你可以有一个类似的方法:

    @Inject
    foo(SampleManager manager){...}
    

    Guice 会为你注入。

    获取注入器适用于由于某种原因这不起作用的情况,例如,如果您需要将注入的值与调用函数提供的值混合使用。一般不建议直接使用喷油器,大部分情况下有一定的模式可以避免。

    【讨论】:

    • 太棒了,感谢您的回答。很有帮助。另一个问题......你说绑定是必要的。我浏览了我们的企业应用程序,发现大多数注入的类在任何地方都没有任何绑定。绑定仅适用于实现接口的类吗?这些类都使用了 Singleton 注释,但没有一个使用提供一个..?
    • Guice 注入的所有类都需要绑定。有多种方法可以进行绑定。 @Provides 是您在没有bind() 的情况下进行绑定的方法上的注释。例如。 @Provides Foo provideFoo(){return new Foo();} 将是一个绑定Foo 类的方法,而不使用bind() 方法。 Guice 注入的任何东西都需要绑定在某个地方,在几个常用的库类之外,比如 Guice Injector 类或日志类等。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多