Google Guice:公开一个命名对象,但在没有名称的情况下在模块中保持可用

Google Guice: expose a named object but keep it available within the module without a name

我的应用程序是使用 Guice 和 MyBatis 构建的。 使用 javax.sql.DataSource 表示不同的数据库连接。 所有需要访问 DataSource 的 类 都在提供此 DataSource 的同一个 Guice PrivateModule 中声明。 但是,这些模块会随着时间的推移而增长并且更难管理。此外,我希望能够将不同的 DAO 及其相关 类 绑定到一个单独的 Guice 模块中,并为该模块提供数据源,以便更好地封装上述模块并可与不同的数据源一起重用。

从技术上讲,我希望能够编写如下内容:

public class MyDataSourceModule extends PrivateModule {

   @Override
   protected void configure() {}

   @Exposed
   @Named("systemDataSource")
   @Singleton
   @Provides
   DataSource provideDataSource() {
       return ...;
   }
}

这样 DataSource 在模块内仍然可用,但没有名称,但只有在模块外有名称。可以根据需要更改注释。这可能吗?如何实现?

通过在同一模块中创建两个不同的绑定,可以实现您想要的。

(旁注:如果您不熟悉 BindingAnnotations,可以了解更多信息 here。在我的示例中,我将使用 @UsingSystemDataSource 作为绑定注释。)

configure()方法中使用EDSL:

protected void configure() {
    // binding for private use
    bind(DataSource.class).to(SystemDataSourceImpl.class).in(Scopes.SINGLETON);

    // binding for public use
    bind(DataSource.class).annotatedWith(@UsingSystemDataSource.class).to(DataSource.class);
    expose(DataSource.class).annotatedWith(@UsingSystemDataSource.class);
}

现在,如果您需要在不使用 EDSL 的情况下执行此操作,那么您的私有模块 @Provides 方法将如下所示:

@Provides
@Exposed
@UsingSystemDataSource
DataSource provideDataSourcePublicly(DataSource privatelyBoundDatasource) {
    return privatelyBoundDatasource;
}

@Provides
@Singleton
DataSource provideDataSource() {
    return ...;
}

为什么这会起作用?

这实际上创建了两个不同的绑定——一个将 DataSource 链接到 SystemDataSource,另一个将 @UsingSystemDataSource DataSource 链接到 DataSource。使用 expose() 方法或 @Exposed,私有模块 仅公开 绑定的注释版本。 (我找不到明确说明它适用于这个用例的来源,所以我自己测试了它。)