Guice 简明教程

Google Guice - Overview

Guice 是基于 Java 的开源依赖注入框架。它非常轻量,并且由 Google 积极开发/管理。

Guice is an open source, Java-based dependency injection framework. It is quiet lightweight and is actively developed/managed by Google.

Dependency Injection

每个基于 Java 的应用程序都有一些对象可以协同工作,以展示最终用户所看到的工作应用程序。在编写复杂的 Java 应用程序时,应用程序类应尽可能独立于其他 Java 类,以增加重用这些类并使其独立于其他类进行单​​元测试的可能性。依赖注入(或有时称为连接)有助于将这些类粘合在一起,同时又保持它们独立性。

Every Java-based application has a few objects that work together to present what the end-user sees as a working application. When writing a complex Java application, application classes should be as independent as possible of other Java classes to increase the possibility to reuse these classes and to test them independently of other classes while unit testing. Dependency Injection (or sometime called wiring) helps in gluing these classes together and at the same time keeping them independent.

考虑您有一个包含文本编辑器组件的应用程序,并且您希望提供拼写检查。您的标准代码将如下所示 −

Consider you have an application which has a text editor component and you want to provide a spell check. Your standard code would look something like this −

public class TextEditor {
   private SpellChecker spellChecker;

   public TextEditor() {
      spellChecker = new SpellChecker();
   }
}

我们在此处所做的是创建 TextEditor 和 SpellChecker 之间的依赖关系。在控制反转场景中,我们改为执行类似以下操作 −

What we’ve done here is, create a dependency between the TextEditor and the SpellChecker. In an inversion of control scenario, we would instead do something like this −

public class TextEditor {
   private SpellChecker spellChecker;

   @Inject
   public TextEditor(SpellChecker spellChecker) {
      this.spellChecker = spellChecker;
   }
}

在此,TextEditor 应该不用担心 SpellChecker 的实现。SpellChecker 将独立实现,并且在 TextEditor 实例化时提供给 TextEditor。

Here, the TextEditor should not worry about SpellChecker implementation. The SpellChecker will be implemented independently and will be provided to the TextEditor at the time of TextEditor instantiation.

Dependency Injection using Guice (Binding)

依赖注入受 Guice Binding 控制。Guice 使用绑定将对象类型映射到其实际实现。这些绑定定义了一个模块。模块是一组绑定,如下所示:

Dependency Injection is controlled by the Guice Bindings. Guice uses bindings to map object types to their actual implementations. These bindings are defined a module. A module is a collection of bindings as shown below:

public class TextEditorModule extends AbstractModule {
   @Override
   protected void configure() {
      /*
      * Bind SpellChecker binding to WinWordSpellChecker implementation
      * whenever spellChecker dependency is used.
      */
      bind(SpellChecker.class).to(WinWordSpellChecker.class);
   }
}

模块是 Guice 对象图生成器的 Injector 的核心构建模块。第一步是创建 injector,然后我们可以使用 injector 获取对象。

The Module is the core building block for an Injector which is Guice’s object-graph builder. First step is to create an injector and then we can use the injector to get the objects.

public static void main(String[] args) {
   /*
   * Guice.createInjector() takes Modules, and returns a new Injector
   * instance. This method is to be called once during application startup.
   */
   Injector injector = Guice.createInjector(new TextEditorModule());
   /*
   * Build object using injector
   */
   TextEditor textEditor = injector.getInstance(TextEditor.class);
}

在上述示例中,TextEditor 类对象图由 Guice 构建,并且此图包含 TextEditor 对象及其作为 WinWordSpellChecker 对象的依赖项。

In above example, TextEditor class object graph is constructed by Guice and this graph contains TextEditor object and its dependency as WinWordSpellChecker object.