首页 > 解决方案 > 在这个例子中,spring 框架是如何知道如何实例化 RestHighLevelClient 的呢?

问题描述

我正在关注这篇文章,它解释了如何使用 Java High Level REST Client (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()呢?

标签: javaspringresthighlevelclient

解决方案


Spring 对类进行初始扫描,以确定它将生成哪些 bean。然后它将开始“初始化”阶段。

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

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


从其他评论:

如果有多个 RestHighLevelClient实例正在等待创建或已经在其中,ApplicationContext那么您将得到一个BeanCreationException详细信息,即“候选人太多,预期为 1,但找到了n ”。

这些可以通过多种方式进行。

您可以将其中一个RestHighLevelClientbean注释为@Primary“如果有多个可用,但只需要一个,则使用它”。

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

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


推荐阅读