spring 框架如何知道如何在这个例子中实例化 RestHighLevelClient?

How does spring framework knows how to instantiate RestHighLevelClient in this example?

我正在关注 this post,其中解释了如何使用 Java 高级 REST 客户端 (JHLRC) 连接 ElasticSearch。

这道题的重要部分在ElasticsearchConfig.java:

@Configuration
public class ElasticsearchConfig {

    ...

    @Bean(destroyMethod = "close")
    public RestHighLevelClient restClient() {

        final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
        credentialsProvider.setCredentials(AuthScope.ANY,
                new UsernamePasswordCredentials(userName, password));

        RestClientBuilder builder = RestClient.builder(new HttpHost(host, port))
                .setHttpClientConfigCallback(httpClientBuilder -> httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider));

        RestHighLevelClient client = new RestHighLevelClient(builder);
        return client;

    }


}

ProfileService.java

@Service
public class ProfileService {

    private RestHighLevelClient client;
    private ObjectMapper objectMapper;

    @Autowired
    public ProfileService(RestHighLevelClient client, ObjectMapper objectMapper) {
        this.client = client;
        this.objectMapper = objectMapper;
    }

    ...

我们正在自动装配 RestHighLevelClientObjectMapper,那么 Spring 怎么知道我们需要的 RestHighLevelClient 实例来自 ElasticsearchConfig.restClient()

Spring 对 类 进行初始扫描以确定它将要生成的 bean。然后它将开始 'initialisation' 阶段。

@Bean 注释的方法在@Configuration 注释的类 将被调用,并将结果加载到ApplicationContext。因此 RestHighLevelClient 已创建(通过您拥有的方法)并加载。

然后它会尝试创建 ProfileService 实例。它看到需要一个 RestHighLevelClient 实例(通过构造函数参数)。它会查看 ApplicationContext 以及计划在扫描阶段创建的 bean。由于只有一个 RestHighLevelClient实例没有冲突,所以使用那个实例。


来自其他评论:

如果 多个 RestHighLevelClient 个实例正在等待创建或已经在 ApplicationContext 中,那么您将得到一个 BeanCreationException 详细说明 'too many candidates, expected 1 but found n'.

这些可以通过多种方式实现。

您可以将 RestHighLevelClient 个 bean 中的 一个 注释为 @Primary,这表示 'use this if multiple are available, but only one required'.

您可以使用 @Qualifier 注释构造函数参数,详细说明 要自动装配的多个实例中的哪个

您可以将构造函数参数更改为 Collection<RestHighLevelClient>,这将自动装配 所有 个此类实例,然后您自己在构造函数中进行选择。