繁体   English   中英

通过一些 ref id 连接 Spring bean

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM