跳到主要内容

类别扫描

在本教程中,我们将在没有实现的任意类中定义 @Provides 方法。 模块 接口。 然后我们将扫描这些类来收集提供者, Injector

带有 的类 @提供 方法#

我们将定义两个类,它们包含了用 @Provides 注释的方法。 第一个类 StaticProviders 将只包含静态 @Provides-方法。 另一个类 MixedProviders ,包含静态和实例 @Provides-方法。

public static class StaticProviders {  @Provides  static int port() {    return 1234;  }
  @Provides  static String databaseName() {    return "exampleDB";  }}

StaticProviders 类提供了一个数据库的名称以及一个数据库的端口号。

public static class MixedProviders {  private final String hostname;
  public MixedProviders(String hostname) {    this.hostname = hostname;  }
  @Provides  InetSocketAddress address(int port) {    return new InetSocketAddress(hostname, port);  }
  @Provides  static DataSource dataSource(InetSocketAddress address, String dbName) {    return new DataSource(address, dbName);  }}

MixedProviders 类提供了一个数据库的地址和一个 DataSource 类。 DataSource 类需要一个数据库名称以及一个数据库的地址。 这个班级看起来像这样。

public static final class DataSource {  private final InetSocketAddress address;  private final String dbName;
  @Inject  public DataSource(InetSocketAddress address, String dbName) {    this.address = address;    this.dbName = dbName;  }
  public String queryData() {    System.out.printf("Querying %s:%s for data\n", address, dbName);    return "data";  }}

创建 注射器#

为了创建一个 Injector ,我们需要提供一些DI模块。 但我们只有任意的类,有 @Provides-方法。 我们可以用 模块生成器 类来创建一个基于这些任意类的模块。 ModuleBuilder 有多个 scan() 方法,可用于扫描一个类或一个实例并收集提供者。 整个类的层次结构都会被扫描到,所以定义在超类中的提供者 ,也会被 scan()。 下面是我们如何创建一个 Injector

public static void main(String[] args) {  Injector injector = Injector.of(      ModuleBuilder.create()          .scan(StaticProviders.class)          .scan(new MixedProviders("example.com"))          .build()  );
  DataSource dataSource = injector.getInstance(DataSource.class);  System.out.println(dataSource.queryData());}

对于 StaticProviders ,该类只包含静态提供者,我们不需要一个类的实例。 这就是为什么我们只向 scan() 方法传递一个类。 另外, MixedProviders 类也包含一个非静态的提供者方法,所以我们需要将 MixedProviders 的一个实例传递给 scan() 方法。

所有收集的提供者形成一个新的 模块 ,然后被传递到 Injcetor

你可以在以下网站上找到实例来源 Github