[英]Wire Spring beans by some ref id
我在通过配置连接 bean 时遇到问题。 我有一些 Pipe 需要从某个来源读取数据并以一种或另一种方式处理数据。 数据源和处理数据的方式基于配置值。 在代码中,它的实现类似于以下结构:
class Pipe {
DBReader reader;
List<DataProcessor> dataProcessors;
}
配置了多个相同类型的管道。 每个都可能有一个 DBReader 实现:例如 JDBC 读取器取决于特定数据源或文件读取器取决于某些文件名。 它还可以有 0..n 个 DataProcessor,每个实现也取决于它自己的一组参数。
interface DBReader {
Data readData();
}
class JdbcReader implements DBReader {
DataSource dataSource;
}
class FileReader implements DBReader {
String fileName
}
interface DataProcessor {
void processData(Data data);
}
class CopyDataProcessor implements DataProcessor {
int param1;
int param2;
}
class DevNullDataProcessor implements DataProcessor {
String hostName;
}
在配置中它将是这样的:
datasources:
dataSource:
id: 1
connectionString: "postgres://la-la-la"
dataSource:
id: 2
connectionString: "mysql://la-la-la"
dbReaders:
dbReader:
id: 1
type: jdbc // "com.example.reader.JdbcReader"
dataSourceRef: 1
dbReader:
id: 2
type: file
filename: "customers.json"
dbReader:
id: 3
type: jdbc
dataSourceRef: 2
dataProcessors:
dataProcessor:
id: 1
impl: "com.example.processors.CopyDataProcessor"
param1: 4
param2: 8
dataProcessor:
id: 2
impl: "com.example.processors.DevNullProcessor"
hostName: Alpha
pipes:
pipe:
readerRef: 1
dataProcessorsRef: [1, 2]
pipe:
readerRef: 2
dataProcessorsRef: [2]
是否可以使用基于注释的配置在 Spring 中执行此操作? 我可以通过 id 自动装配 bean 吗? 例如,我可以制作 Spring 来加载所有已配置的数据处理器和读取器,并通过配置中的那些 Refs 连接它们。 也许 Spring 可以将 bean 作为映射加载,然后使用 id 作为 map 的键自动装配? 或者也许我可以使用一些工厂来做到这一点? 可以请任何人指导我正确的方向吗?
最简单的方法是使用限定符:
@Configuration
public class MyConfiguration {
@Bean
@Qualifier("jdbcReader")
public DbReader jdbcReader(String connStr /*read this from @ConfigurationProperties / @Value */) {
return new JdbcReader(connStr);
}
... // other readers here ...
@Bean
@Qualifier("devNullProcessor")
public DataProcessor devNullProcessor() {
return new DevNullProcessor();
}
@Bean
public Pipe samplePipe(@Qualifier("jdbcReader") DbReader reader, @Qualifier("devNullProcessor") DataProcessor processor) {
return new Pipe(reader, processor);
}
}
然而,这意味着配置本身是由程序员在 Java 中完成的。在您的示例中,您似乎想要创建 bean 而无需提前指定它们,仅基于 yaml 配置。
在这种情况下,您可能希望使用允许动态创建 bean 的BeanFactoryPostProcessor
。 不过,这与我上面描述的方法完全不同。
简而言之,它是您可以实现的 spring 的抽象(接口)。 当应用程序上下文启动时,它将由 Spring 调用,并将允许注册 bean 定义,Spring 稍后将从中创建 bean。 由于它是一个代码,您可以在处理器的实现中注册任意数量的 bean 定义。
inte.net 中有很多使用 bean factory 后处理器的示例。 例如,快速谷歌搜索显示了这个
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.