GoogleGuice:公开一个命名对象,但在没有名称的模块中保持它可用
我的应用程序是使用Guice和MyBatis构建的。 使用javax.sql.DataSource表示不同的数据库连接。 所有需要访问数据源的类都在提供该数据源的同一Guice PrivateModule中声明。 但是,这些模块会随着时间的推移而增长,并且更难管理。此外,我希望能够将不同的DAO及其相关类绑定到一个单独的Guice模块中,并为该模块提供一个数据源,以便更好地封装上述模块,并可在不同的数据源中重用 从技术上讲,我希望能够写出如下内容:GoogleGuice:公开一个命名对象,但在没有名称的模块中保持它可用,guice,Guice,我的应用程序是使用Guice和MyBatis构建的。 使用javax.sql.DataSource表示不同的数据库连接。 所有需要访问数据源的类都在提供该数据源的同一Guice PrivateModule中声明。 但是,这些模块会随着时间的推移而增长,并且更难管理。此外,我希望能够将不同的DAO及其相关类绑定到一个单独的Guice模块中,并为该模块提供一个数据源,以便更好地封装上述模块,并可在不同的数据源中重用 从技术上讲,我希望能够写出如下内容: public class MyDataSour
public class MyDataSourceModule extends PrivateModule {
@Override
protected void configure() {}
@Exposed
@Named("systemDataSource")
@Singleton
@Provides
DataSource provideDataSource() {
return ...;
}
}
这样,数据源在模块内没有名称但仅在模块外有名称时仍然可用。注释可以根据需要进行更改。这是可能的吗?如何实现?通过在同一模块中创建两个不同的绑定,可以实现您想要的 (旁注:如果您不熟悉BindingAnnotation,您可以了解更多。在我的示例中,我将使用
@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
@Exposed
@UsingSystemDataSource
DataSource provideDataSourcePublicly(DataSource privatelyBoundDatasource) {
return privatelyBoundDatasource;
}
@Provides
@Singleton
DataSource provideDataSource() {
return ...;
}
为什么这样做有效?
这实际上创建了两个不同的绑定,一个链接到DataSource
到SystemDataSource
,另一个链接到@UsingSystemDataSource-DataSource
到DataSource
。使用expose()
方法或@Exposed
,专用模块仅公开带注释的绑定版本。(我找不到明确说明它适用于此用例的源代码,所以我自己测试了它。)您是否尝试过自己的代码示例?乍一看,我看不出它有什么不起作用的原因。您是否尝试过我的代码示例,或者只是看了一眼?:-)一旦你@命名了某个东西,就很难只按类型而不按名称访问它。不,我还没有机会运行它。您是否有一些约束要求您使用@Provides
方法,或者您是否可以使用使用EDSL绑定的解决方案?这很好,但为什么您要创建@UsingSystemDataSource BindingAnnotations而不是使用@Named?这是一种“最佳实践”。Guice建议使用专门构建的注释,因为编译器可以检查它们。(编译器无法查看@Named
中的字符串是否正确。)好的,但是运行时在启动时会非常快。我喜欢命名的概念和它内置的事实。但这并没有改变答案多少。