我可以在 Spring 中注入 bean 的所有 impl 的 Map

use*_*466 7 java spring spring-boot

我正在编写一项服务,该服务获取输入,我需要根据该输入调用一项服务的某些实现。此输入是需要调用的 impl 的名称列表。

public interface Processor {

  Map<String, String> execute();

} 

@Service("BUCKET_PROCESSOR")
public class BucketProcessor implements Processor {
   ..... //first impl
}

@Service("QUERY_PROCESSOR")
public class QueryProcessor implements Processor {
   ..... //second impl
}

@Service("SQL_PROCESSOR")
public class SQLProcessor implements Processor {
   ..... //third impl
}
Run Code Online (Sandbox Code Playgroud)

然后我有一个服务,我想在其中注入所有这些 impl 的映射,以便我可以迭代输入并调用相应的 impl。

@Service
public class MyAysncClient {

    @Autowired
    private Map<String, Processor> processorMap;  

    public void execute(List<String> processors) {

        List<Future> tasks = new ArrayList<>();

        for (String p : processors) {
            final Processor processor = this.processorMap.get(p);
            processor.execute()

            ....
        }

    }
}
Run Code Online (Sandbox Code Playgroud)

tsa*_*txt 10

你可以只使用getBeansOfType(Processor.class)

返回一个包含匹配 bean 的 Map,其中包含 bean 名称作为键,包含相应的 bean 实例作为值

    @Bean
    public Map<String, Processor> processorMap(ApplicationContext context) {
        return context.getBeansOfType(Processor.class);
    }
Run Code Online (Sandbox Code Playgroud)


Mar*_*nik 8

是的,你可以 - spring 默认启用此功能。也就是说,您可以定义将 a 注入Map<String, Processor>到 spring bean 中。

这将指示 spring 查找所有接口实现的 bean Processor,这些将是映射的值,相应的键将是 bean 名称。

所以问题中提出的代码应该可以工作。

查看著名的@Autowired注释的文档。

在“自动装配数组、集合和映射”部分中,说明了以下内容:

对于数组、集合或映射依赖类型,容器会自动装配与声明的值类型匹配的所有 bean。为此,必须将映射键声明为 String 类型,该类型将解析为相应的 bean 名称。这样的容器提供的集合将被排序,考虑目标组件的 Ordered 和 @Order 值,否则遵循它们在容器中的注册顺序。或者,单个匹配的目标 bean 也可能是一般类型化的 Collection 或 Map 本身,因此被注入。

请参阅此示例- 其相关部分是将映射注入到测试中的位置。