@EachProperty 注释是驱动动态配置的好方法,但通常您希望将该配置注入到依赖它的另一个 bean 中。使用硬编码限定符注入单个实例不是一个很好的解决方案,因此 @EachProperty 通常与 @EachBean 结合使用:
使用@EachBean
Java |
Groovy |
Kotlin |
@Factory // (1)
public class DataSourceFactory {
@EachBean(DataSourceConfiguration.class) // (2)
DataSource dataSource(DataSourceConfiguration configuration) { // (3)
URI url = configuration.getUrl();
return new DataSource(url);
}
|
@Factory // (1)
class DataSourceFactory {
@EachBean(DataSourceConfiguration) // (2)
DataSource dataSource(DataSourceConfiguration configuration) { // (3)
URI url = configuration.url
return new DataSource(url)
}
|
@Factory // (1)
class DataSourceFactory {
@EachBean(DataSourceConfiguration::class) // (2)
internal fun dataSource(configuration: DataSourceConfiguration): DataSource { // (3)
val url = configuration.url
return DataSource(url)
}
|
上面的示例定义了一个创建 javax.sql.DataSource 实例的 bean Factory。
@EachBean 注释表示将为上一节中定义的每个 DataSourceConfiguration 创建一个新的 DataSource bean。
DataSourceConfiguration 实例作为方法参数注入并用于驱动每个 javax.sql.DataSource 的配置
请注意,@EachBean 要求父 bean 具有 @Named 限定符,因为该限定符由 @EachBean 创建的每个 bean 继承。
换句话说,要检索由 test.datasource.one 创建的数据源,您可以执行以下操作:
使用限定符
Java |
Groovy |
Kotlin |
Collection<DataSource> beansOfType = applicationContext.getBeansOfType(DataSource.class);
assertEquals(2, beansOfType.size()); // (1)
DataSource firstConfig = applicationContext.getBean(
DataSource.class,
Qualifiers.byName("one") // (2)
);
|
when:
Collection<DataSource> beansOfType = applicationContext.getBeansOfType(DataSource)
assertEquals(2, beansOfType.size()) // (1)
DataSource firstConfig = applicationContext.getBean(
DataSource,
Qualifiers.byName("one") // (2)
)
|
val beansOfType = applicationContext.getBeansOfType(DataSource::class.java)
assertEquals(2, beansOfType.size) // (1)
val firstConfig = applicationContext.getBean(
DataSource::class.java,
Qualifiers.byName("one") // (2)
)
|
我们在这里证明确实有两个数据源。我们怎样才能得到一个特别的?
通过使用 Qualifiers.byName("one"),我们可以选择我们想要引用的两个 bean 中的哪一个。
更多建议: