Elastic Spring Boot Starter
文章目录
此Starter使用的版本
- elasticsearch-rest-high-level-client 7.2.0
- elasticsearch-rest-client 7.2.0
- elasticsearch
- elastic 7.*
为什么写这个Starter
公司的Elastic版本还是6.x,而且使用的transportClient,作为客户端。一则再升级版本会面临客户端不支持,另外一个官方也已经不再推荐使用transportClient,写这个Starter练练手,另外有备无患。
如何写一个SpringBoot的Starter
写一个Starter相对来说其实很简单,按约定格式引入依赖,加入一个spring.factories
文件即可。
-
创建一个Maven项目,名称使用
xxx-spring-boot-starter
命名,以便和官方的Starter区分开,比如au92-elastic-spring-boot-starter
-
POM引用,实际需要用到的依赖包只有两个
1 2 3 4 5 6 7 8 9
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency>
-
resources
目录创建文件夹META-INF
,新建一个spring.factories
文件1 2
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.au92.common.elastic.ElasticSearchAutoConfiguration
-
创建一个
ElasticSearchProperties
类加载配置信息1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
package com.au92.common.elastic; import lombok.Data; import org.apache.commons.lang3.StringUtils; import org.springframework.boot.context.properties.ConfigurationProperties; /** * @author: p_x_c */ @Data @ConfigurationProperties(prefix = "elasticsearch") public class ElasticSearchProperties { /** * es集群地址,多个用英文逗号分开 */ private String clusterNodes = "http://127.0.0.1:9200"; /** * es 用户名 */ private String userName = StringUtils.EMPTY; /** * es 用户密码 */ private String password = StringUtils.EMPTY; /** * 默认es索引名称 */ private String index = "default"; }
-
新建
ElasticSearchAutoConfiguration
用来将配置自动加载进来1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
package com.au92.common.elastic; import lombok.extern.slf4j.Slf4j; import org.apache.http.HttpHost; import org.elasticsearch.client.RestClient; import org.elasticsearch.client.RestClientBuilder; import org.elasticsearch.client.RestHighLevelClient; import org.springframework.beans.factory.DisposableBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Scope; import javax.annotation.Resource; import java.io.IOException; import java.util.Arrays; import java.util.Objects; import java.util.stream.Collectors; import static org.springframework.beans.factory.config.ConfigurableBeanFactory.SCOPE_PROTOTYPE; /** * @author: p_x_c */ @Slf4j @Configuration @EnableConfigurationProperties(ElasticSearchProperties.class) public class ElasticSearchAutoConfiguration implements DisposableBean { private RestHighLevelClient client; @Resource private ElasticSearchProperties properties; @Override public void destroy() throws Exception { log.info("销毁ES连接"); if (client != null) { client.close(); } } /** * 创建client * * @return * @throws IOException */ @Bean @ConditionalOnMissingBean(RestHighLevelClient.class) public RestHighLevelClient client() throws IOException { if (!Objects.equals(null, client)) { log.warn("client对象没有正确关闭"); client.close(); } RestClientBuilder builder = RestClient.builder(setting()); setConnectTimeOutConfig(builder); setMutiConnectConfig(builder); client = new RestHighLevelClient(builder); return client; } /** * Elastic Service * * @return */ @Bean @Scope(value = SCOPE_PROTOTYPE) @ConditionalOnMissingBean(IElasticSearchService.class) public IElasticSearchService service() { return new ElasticSearchServiceImpl(); } /** * 解析配置文件 * * @return */ private HttpHost[] setting() { return Arrays.stream(properties.getClusterNodes().split(ElasticConstant.CLUSTER_SPLIT)) .map(x -> { String[] addressPortPairs = x.split(ElasticConstant.SCHEME_SPLIT); String schemeName = addressPortPairs[0].toLowerCase(); String hostname = addressPortPairs[1].substring(2); Integer port = Integer.valueOf(addressPortPairs[2]); return new HttpHost(hostname, port, schemeName); }) .collect(Collectors.toList()) .toArray(new HttpHost[0]); } /** * 超时设置 * * @param builder */ private void setConnectTimeOutConfig(RestClientBuilder builder) { builder.setRequestConfigCallback(requestConfigBuilder -> { requestConfigBuilder.setConnectTimeout(ElasticConstant.CONNECT_TIME_OUT) .setSocketTimeout(ElasticConstant.SOCKET_TIME_OUT) .setConnectionRequestTimeout(ElasticConstant.CONNECTION_REQUEST_TIME_OUT); return requestConfigBuilder; }); } /** * 并发连接数设置 * * @param builder */ private void setMutiConnectConfig(RestClientBuilder builder) { builder.setHttpClientConfigCallback(httpClientBuilder -> { httpClientBuilder.setMaxConnTotal(ElasticConstant.MAX_CONNECT_NUM) .setMaxConnPerRoute(ElasticConstant.MAX_CONNECT_PER_ROUTE); return httpClientBuilder; }); } }
抛开其他业务相关的逻辑,一个Spring Boot的Starter已经可以算完成了。
用到的其他工具类和一些操作类
https://gist.github.com/Chairo/1b0d06d45e5155b134b7b43abb3d84f6
文章作者 P.X.C
上次更新 2019-10-03
许可协议 不允许任何形式转载。