Как Spring framework знает, как создать экземпляр 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;
    }

    ...

Мы проводим электромонтаж RestHighLevelClient а также ObjectMapper, откуда Spring знает, что RestHighLevelClient нужный нам пример исходит из ElasticsearchConfig.restClient()?

1 ответ

Решение

Spring выполняет начальное сканирование классов, чтобы определить, какие bean-компоненты он собирается создавать. Затем начнется фаза "инициализации".

@Bean аннотированные методы в @Configuration аннотированные классы будут вызваны, и результат будет загружен в ApplicationContext. ИтакRestHighLevelClient создается (с помощью имеющегося у вас метода) и загружается.

Затем он пытается создать ProfileServiceпример. Он видит, чтоRestHighLevelClientтребуется экземпляр (по параметру конструктора). Это выглядит вApplicationContextа также bean-компоненты, запланированные для создания на этапе сканирования. Поскольку есть только один RestHighLevelClient instance, конфликта нет, поэтому используется этот экземпляр.


Из других комментариев:

Если есть несколько RestHighLevelClient экземпляры либо ожидающие создания, либо уже в ApplicationContext тогда вы получите BeanCreationExceptionподробно описывая, что "слишком много кандидатов, ожидалось 1, но найдено n".

С ними можно работать несколькими способами.

Вы можете добавить аннотацию к одному изRestHighLevelClient фасоль как @Primary что означает "используйте это, если доступно несколько, но требуется только один".

Вы можете аннотировать параметр конструктора с помощью @Qualifierс подробным описанием того, какой из нескольких экземпляров следует автоматически подключить.

Вы можете изменить параметр конструктора на Collection<RestHighLevelClient>который автоматически подключит все такие экземпляры, а затем сделает выбор самостоятельно в конструкторе.

Другие вопросы по тегам