序
本文主要研究一下springboot jest autoconfigure
JestProperties
spring-boot-autoconfigure-2.1.4.RELEASE-sources.jar!/org/springframework/boot/autoconfigure/elasticsearch/jest/JestProperties.java
@ConfigurationProperties(prefix = "spring.elasticsearch.jest")
public class JestProperties {
/**
* Comma-separated list of the Elasticsearch instances to use.
*/
private List<String> uris = new ArrayList<>(
Collections.singletonList("http://localhost:9200"));
/**
* Login username.
*/
private String username;
/**
* Login password.
*/
private String password;
/**
* Whether to enable connection requests from multiple execution threads.
*/
private boolean multiThreaded = true;
/**
* Connection timeout.
*/
private Duration connectionTimeout = Duration.ofSeconds(3);
/**
* Read timeout.
*/
private Duration readTimeout = Duration.ofSeconds(3);
/**
* Proxy settings.
*/
private final Proxy proxy = new Proxy();
//......
public static class Proxy {
/**
* Proxy host the HTTP client should use.
*/
private String host;
/**
* Proxy port the HTTP client should use.
*/
private Integer port;
public String getHost() {
return this.host;
}
public void setHost(String host) {
this.host = host;
}
public Integer getPort() {
return this.port;
}
public void setPort(Integer port) {
this.port = port;
}
}
}
复制代码
- JestProperties提供了uris、username、password、multiThreaded(
默认true
)、connectionTimeout(默认3s
)、readTimeout(默认3s
)、proxy的配置
JestAutoConfiguration
spring-boot-autoconfigure-2.1.4.RELEASE-sources.jar!/org/springframework/boot/autoconfigure/elasticsearch/jest/JestAutoConfiguration.java
@Configuration
@ConditionalOnClass(JestClient.class)
@EnableConfigurationProperties(JestProperties.class)
@AutoConfigureAfter(GsonAutoConfiguration.class)
public class JestAutoConfiguration {
private final JestProperties properties;
private final ObjectProvider<Gson> gsonProvider;
private final ObjectProvider<HttpClientConfigBuilderCustomizer> builderCustomizers;
public JestAutoConfiguration(JestProperties properties, ObjectProvider<Gson> gson,
ObjectProvider<HttpClientConfigBuilderCustomizer> builderCustomizers) {
this.properties = properties;
this.gsonProvider = gson;
this.builderCustomizers = builderCustomizers;
}
@Bean(destroyMethod = "shutdownClient")
@ConditionalOnMissingBean
public JestClient jestClient() {
JestClientFactory factory = new JestClientFactory();
factory.setHttpClientConfig(createHttpClientConfig());
return factory.getObject();
}
protected HttpClientConfig createHttpClientConfig() {
HttpClientConfig.Builder builder = new HttpClientConfig.Builder(
this.properties.getUris());
PropertyMapper map = PropertyMapper.get();
map.from(this.properties::getUsername).whenHasText().to((username) -> builder
.defaultCredentials(username, this.properties.getPassword()));
Proxy proxy = this.properties.getProxy();
map.from(proxy::getHost).whenHasText().to((host) -> {
Assert.notNull(proxy.getPort(), "Proxy port must not be null");
builder.proxy(new HttpHost(host, proxy.getPort()));
});
map.from(this.gsonProvider::getIfUnique).whenNonNull().to(builder::gson);
map.from(this.properties::isMultiThreaded).to(builder::multiThreaded);
map.from(this.properties::getConnectionTimeout).whenNonNull()
.asInt(Duration::toMillis).to(builder::connTimeout);
map.from(this.properties::getReadTimeout).whenNonNull().asInt(Duration::toMillis)
.to(builder::readTimeout);
customize(builder);
return builder.build();
}
private void customize(HttpClientConfig.Builder builder) {
this.builderCustomizers.orderedStream()
.forEach((customizer) -> customizer.customize(builder));
}
}
复制代码
- JestAutoConfiguration在没有jestClient的bean情况下会通过JestProperties创建了HttpClientConfig,然后使用JestClientFactory创建JestClient,同时标记其destroyMethod为shutdownClient方法
JestClientFactory
jest-6.3.1-sources.jar!/io/searchbox/client/JestClientFactory.java
public class JestClientFactory {
final static Logger log = LoggerFactory.getLogger(JestClientFactory.class);
private HttpClientConfig httpClientConfig;
public JestClient getObject() {
JestHttpClient client = new JestHttpClient();
if (httpClientConfig == null) {
log.debug("There is no configuration to create http client. Going to create simple client with default values");
httpClientConfig = new HttpClientConfig.Builder("http://localhost:9200").build();
}
client.setRequestCompressionEnabled(httpClientConfig.isRequestCompressionEnabled());
client.setServers(httpClientConfig.getServerList());
final HttpClientConnectionManager connectionManager = getConnectionManager();
final NHttpClientConnectionManager asyncConnectionManager = getAsyncConnectionManager();
client.setHttpClient(createHttpClient(connectionManager));
client.setAsyncClient(createAsyncHttpClient(asyncConnectionManager));
// set custom gson instance
Gson gson = httpClientConfig.getGson();
if (gson == null) {
log.info("Using default GSON instance");
} else {
log.info("Using custom GSON instance");
client.setGson(gson);
}
// set discovery (should be set after setting the httpClient on jestClient)
if (httpClientConfig.isDiscoveryEnabled()) {
log.info("Node Discovery enabled...");
if (!Strings.isNullOrEmpty(httpClientConfig.getDiscoveryFilter())) {
log.info("Node Discovery filtering nodes on \"{}\"", httpClientConfig.getDiscoveryFilter());
}
NodeChecker nodeChecker = createNodeChecker(client, httpClientConfig);
client.setNodeChecker(nodeChecker);
nodeChecker.startAsync();
nodeChecker.awaitRunning();
} else {
log.info("Node Discovery disabled...");
}
// schedule idle connection reaping if configured
if (httpClientConfig.getMaxConnectionIdleTime() > 0) {
log.info("Idle connection reaping enabled...");
IdleConnectionReaper reaper = new IdleConnectionReaper(httpClientConfig, new HttpReapableConnectionManager(connectionManager, asyncConnectionManager));
client.setIdleConnectionReaper(reaper);
reaper.startAsync();
reaper.awaitRunning();
} else {
log.info("Idle connection reaping disabled...");
}
Set<HttpHost> preemptiveAuthTargetHosts = httpClientConfig.getPreemptiveAuthTargetHosts();
if (!preemptiveAuthTargetHosts.isEmpty()) {
log.info("Authentication cache set for preemptive authentication");
client.setHttpClientContextTemplate(createPreemptiveAuthContext(preemptiveAuthTargetHosts));
}
client.setElasticsearchVersion(httpClientConfig.getElasticsearchVersion());
return client;
}
public void setHttpClientConfig(HttpClientConfig httpClientConfig) {
this.httpClientConfig = httpClientConfig;
}
//......
}
复制代码
- JestClientFactory的getObject方法首先创建JestHttpClient,然后设置HttpClient、AsyncClient
- 如果isDiscoveryEnabled为true则会创建NodeChecker并执行Node Discovery
- 如果maxConnectionIdleTime大于0则会创建IdleConnectionReaper,进行Idle connection reaping
小结
- JestProperties提供了uris、username、password、multiThreaded(
默认true
)、connectionTimeout(默认3s
)、readTimeout(默认3s
)、proxy的配置 - JestAutoConfiguration在没有jestClient的bean情况下会通过JestProperties创建了HttpClientConfig,然后使用JestClientFactory创建JestClient,同时标记其destroyMethod为shutdownClient方法
- JestClientFactory的getObject方法首先创建JestHttpClient,然后设置HttpClient、AsyncClient;如果isDiscoveryEnabled为true则会创建NodeChecker并执行Node Discovery;如果maxConnectionIdleTime大于0则会创建IdleConnectionReaper,进行Idle connection reaping