Google Guice:公开已命名的对象,但保持其在模块中的可用状态而无需命名

时间:2018-09-20 06:46:58

标签: guice

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

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

public class MyDataSourceModule extends PrivateModule {

   @Override
   protected void configure() {}

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

,这样数据源将仍然可用,而无需在模块内使用名称,而仅在模块外使用名称。注释可以根据需要进行更改。那有可能吗?

1 个答案:

答案 0 :(得分:1)

通过在同一模块中创建两个不同的绑定,可以实现所需的操作。

(附带说明:如果您不熟悉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,私有模块公开 only 绑定的注释版本。 (我找不到明确指出适用于该用例的源,因此我自己进行了测试。)