Как 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;
}
}
@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>
который автоматически подключит все такие экземпляры, а затем сделает выбор самостоятельно в конструкторе.