spring 框架如何知道如何在这个例子中实例化 RestHighLevelClient?
How does spring framework knows how to instantiate RestHighLevelClient in this example?
我正在关注 this post,其中解释了如何使用 Java 高级 REST 客户端 (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()
?
Spring 对 类 进行初始扫描以确定它将要生成的 bean。然后它将开始 'initialisation' 阶段。
@Bean
注释的方法在@Configuration
注释的类 将被调用,并将结果加载到ApplicationContext
。因此 RestHighLevelClient
已创建(通过您拥有的方法)并加载。
然后它会尝试创建 ProfileService
实例。它看到需要一个 RestHighLevelClient
实例(通过构造函数参数)。它会查看 ApplicationContext
以及计划在扫描阶段创建的 bean。由于只有一个 RestHighLevelClient
实例没有冲突,所以使用那个实例。
来自其他评论:
如果 多个 RestHighLevelClient
个实例正在等待创建或已经在 ApplicationContext
中,那么您将得到一个 BeanCreationException
详细说明 'too many candidates, expected 1 but found n'.
这些可以通过多种方式实现。
您可以将 RestHighLevelClient
个 bean 中的 一个 注释为 @Primary
,这表示 'use this if multiple are available, but only one required'.
您可以使用 @Qualifier
注释构造函数参数,详细说明 要自动装配的多个实例中的哪个 。
您可以将构造函数参数更改为 Collection<RestHighLevelClient>
,这将自动装配 所有 个此类实例,然后您自己在构造函数中进行选择。
我正在关注 this post,其中解释了如何使用 Java 高级 REST 客户端 (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()
?
Spring 对 类 进行初始扫描以确定它将要生成的 bean。然后它将开始 'initialisation' 阶段。
@Bean
注释的方法在@Configuration
注释的类 将被调用,并将结果加载到ApplicationContext
。因此 RestHighLevelClient
已创建(通过您拥有的方法)并加载。
然后它会尝试创建 ProfileService
实例。它看到需要一个 RestHighLevelClient
实例(通过构造函数参数)。它会查看 ApplicationContext
以及计划在扫描阶段创建的 bean。由于只有一个 RestHighLevelClient
实例没有冲突,所以使用那个实例。
来自其他评论:
如果 多个 RestHighLevelClient
个实例正在等待创建或已经在 ApplicationContext
中,那么您将得到一个 BeanCreationException
详细说明 'too many candidates, expected 1 but found n'.
这些可以通过多种方式实现。
您可以将 RestHighLevelClient
个 bean 中的 一个 注释为 @Primary
,这表示 'use this if multiple are available, but only one required'.
您可以使用 @Qualifier
注释构造函数参数,详细说明 要自动装配的多个实例中的哪个 。
您可以将构造函数参数更改为 Collection<RestHighLevelClient>
,这将自动装配 所有 个此类实例,然后您自己在构造函数中进行选择。