我正在关注this post其中解释了如何使用 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;
}
...
我们正在 Autowiring RestHighLevelClient
和 ObjectMapper
,那么 Spring 如何知道我们需要的 RestHighLevelClient
实例来自 ElasticsearchConfig.restClient ()
?
最佳答案
Spring 对类进行初始扫描,以确定它将生成哪些 bean。然后它将开始“初始化”阶段。
@Bean
@Configuration
中带注释的方法带注释的类将被调用,并将结果加载到 ApplicationContext
。所以RestHighLevelClient
被创建(通过您拥有的方法)并加载。
然后它尝试创建 ProfileService
实例。它看到 RestHighLevelClient
需要实例(通过构造函数参数)。它看起来在 ApplicationContext
以及计划在扫描阶段创建的 bean。因为只有一个 RestHighLevelClient
实例不存在冲突,因此使用该实例。
来自其他评论:
如果有多个 RestHighLevelClient
实例要么正在等待创建,要么已经在 ApplicationContext
中那么你会得到一个BeanCreationException
详细说明“候选人太多,预计有 1 个,但发现 n”。
这些可以通过多种方式实现。
您可以注释 RestHighLevelClient
中的一个 bean 为@Primary
表示“如果有多个可用,但只需要一个,则使用此选项”。
您可以使用 @Qualifier
注释构造函数参数详细说明要 Autowiring 多个实例中的哪个实例。
您可以将构造函数参数更改为 Collection<RestHighLevelClient>
它将 Autowiring 所有这样的实例,然后在构造函数中自己进行选择。
关于java - spring框架如何知道如何在这个例子中实例化RestHighLevelClient?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60179536/