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
,私有模块 仅公开 绑定的注释版本。 (我找不到明确说明它适用于这个用例的来源,所以我自己测试了它。)
我的应用程序是使用 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
,私有模块 仅公开 绑定的注释版本。 (我找不到明确说明它适用于这个用例的来源,所以我自己测试了它。)