Spring Boot 2.1.X整合最新版本Elasticsearch的相關問題
Spring boot 2.1.X整合Elasticsearch最新版的一處問題
新版本的Spring boot 2的spring-boot-starter-data-elasticsearch中支持的Elasticsearch版本是2.X,但Elasticsearch實際上已經發展到6.5.X版本了,為了更好的使用Elasticsearch的新特性,所以棄用了spring-boot-starter-data-elasticsearch依賴,而改為直接使用Spring-data-elasticsearch,以便啟用對新版本支持,目前的版本對應關係如下
打開今日頭條,查看更多圖片其實4.X版本已經處於Dev狀態了,但是考慮到穩定性,本著夠用就好原則,就使用最新的3.1.3發布版本吧
先在gradle里添加好依賴
compile("org.springframework.data:spring-data-elasticsearch:3.1.3.RELEASE")
1
注意一定要去掉spring-boot-starter-data-elasticsearch的依賴,否則不會使用新版本
在yml中添加elasticsearch配置
elasticsearch:
cluster-name: wetodo-search
host: 127.0.0.1
port: 9300
pool: 5
1
2
3
4
5
編寫配置類
package com.wetodo.api.config;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.client.Client;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories;
import java.net.InetAddress;
/**
* @ClassName ElasticConfig
* @Description ElasticSearch搜索引擎配置
* @Author wangd
* @Create 2018-12-02 23:22
*/
@Configuration
@EnableElasticsearchRepositories(basePackages = "com.wetodo.api.dao")
@Slf4j
public class ElasticConfig {
/**
* 主機
*/
@Value("${elasticsearch.host}")
private String esHost;
/**
* 傳輸層埠,注意和ES的Restful API默認9200埠有區分
*/
@Value("${elasticsearch.port}")
private int esPort;
/**
* 集群名稱
*/
@Value("${elasticsearch.clustername}")
private String esClusterName;
/**
* 連接池
*/
@Value("${elasticsearch.pool}")
private String poolSize;
@Bean
public Client client() {
log.info("開始初始化Elasticsearch");
try {
Settings esSettings = Settings.builder()
.put("cluster.name", esClusterName)
.put("client.transport.sniff", true)//增加嗅探機制,找到ES集群
.put("thread_pool.search.size", Integer.parseInt(poolSize))//增加線程池個數,暫時設為5
.build();
//https://www.elastic.co/guide/en/elasticsearch/guide/current/_transport_client_versus_node_client.html
return new PreBuiltTransportClient(esSettings)
.addTransportAddress(new TransportAddress(InetAddress.getByName(esHost), esPort));
} catch (Exception e) {
log.error("初始化Elasticsearch失敗!", e);
return null;
}
}
@Bean
public ElasticsearchOperations elasticsearchTemplate() {
Client client = client();
if (client != null) {
return new ElasticsearchTemplate(client);
} else {
//彈出自定義異常對象
throw new ApiException("初始化Elasticsearch失敗!", 100011);
}
}
//Embedded Elasticsearch Server
/*@Bean
public ElasticsearchOperations elasticsearchTemplate() {
return new ElasticsearchTemplate(nodeBuilder().local(true).node().client());
}*/
}
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
如果現在啟動,會報一個異常,這個異常困擾我很長時間,異常信息如下:
Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.support.BeanDefinitionOverrideException: Invalid bean definition with name "elasticsearchTemplate" defined in class path resource [org/springframework/boot/autoconfigure/data/elasticsearch/ElasticsearchDataAutoConfiguration.class]:
Cannot register bean definition [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false;
factoryBeanName=org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration; factoryMethodName=elasticsearchTemplate; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/data/elasticsearch/ElasticsearchDataAutoConfiguration.class]] for bean "elasticsearchTemplate": There is already [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=elasticConfig;
factoryMethodName=elasticsearchTemplate; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [com/wetodo/api/config/ElasticConfig.class]] bound.
1
2
3
4
對比源碼,發現上述問題的根源是我自定義的Config類里注入bean方法
@Bean
public ElasticsearchOperations **elasticsearchTemplate**() {
Client client = client();
if (client != null) {
return new ElasticsearchTemplate(client);
} else {
//彈出自定義異常對象
throw new ApiException("初始化Elasticsearch失敗!", 100011);
}
}
1
2
3
4
5
6
7
8
9
10
與org.springframework.boot.autoconfigure.ElasticsearchDataAutoConfiguration里的函數同名不同參造成的函數重載衝突
@Bean
@ConditionalOnMissingBean
@ConditionalOnBean(Client.class)
public ElasticsearchTemplate elasticsearchTemplate(Client client,
ElasticsearchConverter converter) {
try {
return new ElasticsearchTemplate(client, converter);
}
catch (Exception ex) {
throw new IllegalStateException(ex);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
自動配置載入類里,多了個converter。。。。。。OK,將我的函數名修為:
@Bean
public ElasticsearchOperations elasticsearchTemplateCustom() {
Client client = client();
if (client != null) {
log.info("初始化Elasticsearch成功!");
return new ElasticsearchTemplate(client);
} else {
//彈出自定義異常對象
throw new ApiException("初始化Elasticsearch失敗!", 100011);
}
}
1
2
3
4
5
6
7
8
9
10
11
重啟,問題解決。
也可以在application.yml顯示的禁用spring自帶的自動配置類:
spring
autoconfigure:
#禁用Spring boot自身的自動配置類
exclude: org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchAutoConfiguration
1
2
3
4
也可以解決。
---------------------
作者:blackhost
原文:https://blog.csdn.net/blackhost/article/details/84769317
※什麼是Serverless無伺服器架構?
※斷路器Netflix OSS Hystrix和Istio的Envoy比較
TAG:程序員小新人學習 |