Как Spring Framework знает, как создать экземпляр RestHighLevelClient в этом примере? - PullRequest
0 голосов
/ 12 февраля 2020

Я слежу за этим сообщением , в котором объясняется, как использовать Java Клиент REST высокого уровня (JHLR C) для соединения с 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 Ответ

1 голос
/ 12 февраля 2020

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

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

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


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

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

Это может быть выполнено несколькими способами.

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

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

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

...