public class FrogMan{@Inject public FrogMan(Vehicle vehicle) { this.vehicle = vehicle; } }
到目前为止,我展示了 @Inject
应用于构造函数的用法。当 Guice 找到注释时,它会挑选构造函数参数,并试图为每个参数找到一个配置绑定。这称为 构造函数注入。根据 Guice 的最佳实践指南,构造函数注入是询问依赖项的首选方式。
public class FrogMan{ private Vehicle vehicle; @Inject public void setVehicle(Vehicle vehicle) { this.vehicle = vehicle; }
注意,我没有使用注入的构造函数,而是改用一个带有 @Inject
标记的方法。Guice 会在构造好 hero 之后立即调用此方法。Spring 框架的忠实用户可以将此方法视为 “setter 注入”。不过,Guice 只关心 @Inject
;您可以任意命名这个方法,它可以带有多个参数。
public class FrogMan{@Inject private Vehicle vehicle; public FrogMan(){}}
同样,所有 Guice 都只关心 @Inject
注释。字段注入查找注释的所有字段并试图注入相应的依赖项。
三个 FrogMan
版本都展示了相同的行为:Guice 在构建时注入相应的 Vehicle
。不过,像 Guice 的作者一样,我更喜欢构造函数注入。下面简单分析这三种方式:
- 构造函数注入 很简单。因为 Java 技术能保证构造函数调用,您不用担心出现未初始化的对象 — 不管是不是由 Guice 创建的。您还可以将字段标记为
final
。
- 字段注入 会影响可测试性,特别是将字段标记为
private
时。这破坏了使用 DI 的主要目的。应该尽量少使用字段注入。
- 方法注入 在您不控制类的实例化时很有用。如果您有一个需要某些依赖项的超类,也可以使用方法注入(构造函数注入会使这种情况变得很复杂)。
然后,使用 Injector
类启动 Guice。通常需要尽早在程序中创建注入器。这样 Guice 能够帮助您创建大部分对象。清单 7 包含一个以 Injector
开始的示例 main 程序:
public class Adventure { public static void main(String[] args){ Injector injector = Guice.createInjector(new HeroModule()); FrogMan hero = injector.getInstance(FrogMan.class); hero.fightCrime(); } }
为了获取注入器,需要在 Guice 类上调用 createInjector
。向 createInjector
传递一个模块列表,用于配置它本身。拥有注入器后,使用 getInstance
向它请求对象,传递您想返回的 Class实例
(细心的读者会注意到您不需要告诉 Guice 有关 FrogMan
的信息。如果您请求一个具体类,而它有一个 @Inject
构造函数或公共非参数构造函数的话,Guice 就会创建这个类,而无需调用 bind
)。这是 Guice 构造对象的第一种方式:显式询问。但是,您不会希望在启动例程之外使用这个操作。更好、更简单的方式是让 Guice 注入依赖项、依赖项的依赖项,依此类推