Springboot3.3.4使用spring-data-elasticsearch整合Elasticsearch7.12.1
Spring Boot 3 不建议使用 Elasticsearch 7.12.1,主要与两者的版本兼容性、技术架构升级及依赖管理机制变化有关,以下是具体原因分析:
一、基础架构与版本依赖的断层
-
Spring Boot 3 的技术栈升级
Spring Boot 3 基于 Java 17 及以上版本构建,底层依赖的 Spring Framework 6 全面采用反应式编程模型(Reactor) 和Kotlin 一等公民支持,并移除了对 Java 8/9/10 的支持。而 Elasticsearch 7.12.1 发布于 2021 年,其官方客户端(如 Elasticsearch Java Client)主要适配 Java 8-11,与 Java 17 的语法特性(如密封类、模式匹配)存在兼容性缺口,可能导致编译错误或运行时异常。 -
Elasticsearch 客户端的版本割裂
- Elasticsearch 7.12.1 对应的官方客户端版本为 7.12.x,该版本仅支持Transport Client(已废弃) 和低版本的 REST Client,无法适配 Spring Boot 3 中主推的Reactive REST Client(需 Elasticsearch 8.0 + 客户端支持)。
- Spring Boot 3 的
spring-data-elasticsearch
依赖已升级至 4.4.x 版本,该版本强制要求 Elasticsearch 服务端版本≥8.0,否则会因 API 接口不匹配导致功能缺失(如无法使用响应式查询 API)。
二、核心功能兼容性问题
-
响应式编程模型不兼容
Spring Boot 3 的spring-data-elasticsearch
模块全面转向响应式编程(ReactiveCrudRepository
、Flux/Mono
返回值),而 Elasticsearch 7.12.1 的客户端仅支持阻塞式操作(RestHighLevelClient
),强行整合会导致:- 无法利用 Spring Boot 3 的非阻塞 IO 特性,反而可能因线程阻塞降低系统吞吐量;
- 需要手动适配异步回调逻辑,增加代码复杂度和维护成本。
-
索引映射与 DSL 语法差异
Elasticsearch 8.0 后对索引映射(Mapping)和查询 DSL 进行了多项优化(如字段类型自动推断、弃用_all
字段),而 Spring Boot 3 的 Elasticsearch 集成模块基于 8.0 + 的语法规范设计。例如:- Spring Boot 3 默认使用
@Document
注解的createIndex = false
(需手动创建索引),而 7.12.1 的自动索引创建机制可能与该配置冲突; - 部分查询 API(如
MatchQuery
的参数构造方式)在 7.12.1 与 8.0 + 之间存在签名变化,可能导致序列化失败或查询结果错误。
- Spring Boot 3 默认使用
三、官方支持与生态演进
-
Elasticsearch 官方的版本建议
Elasticsearch 官方文档明确指出:7.17.x 是 7.x 系列的最后一个长期支持(LTS)版本,而 7.12.1 属于中期版本,已不再提供主流支持(截至 2023 年,该版本已过维护期)。Spring Boot 3 作为 2022 年发布的新一代框架,自然优先适配 Elasticsearch 的 LTS 版本(如 8.0+),以保证稳定性和安全性。 -
依赖管理机制的变化
Spring Boot 3 采用BOM(Bill of Materials) 机制严格管控依赖版本,spring-data-elasticsearch
的 4.4.x 版本会强制引入 Elasticsearch 8.0 + 的客户端依赖。若强行在 Spring Boot 3 中使用 7.12.1,可能引发依赖冲突(如elasticsearch-rest-client
版本不兼容),甚至导致应用无法启动。
但Springboot3依旧是可以通过elasticsearch-rest-client依赖(不能同时存在spring-dataelasticsearch)
elasticsearch7.12.1。下面简单演示一下demo。
1. 引入Maven依赖
在Spring Boot项目的pom.xml
文件中添加Elasticsearch相关的依赖:
<dependencies><!-- Elasticsearch High Level REST Client --><dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-high-level-client</artifactId><version>7.12.1</version></dependency><!-- 其他依赖 --><!-- ... -->
</dependencies>
2. 配置Elasticsearch客户端
创建一个配置类来配置Elasticsearch的RestHighLevelClient:
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class ElasticsearchConfig {@Beanpublic RestHighLevelClient restHighLevelClient() {// 配置Elasticsearch的主机和端口HttpHost httpHost = new HttpHost("localhost", 9200, "http");RestClientBuilder builder = RestClient.builder(httpHost);return new RestHighLevelClient(builder);}
}
3. 创建实体类和索引映射
创建一个实体类来表示Elasticsearch中的文档,并定义一个索引映射模板:
import java.io.Serializable;public class MyDocument implements Serializable {private String id;private String content;// getters and setters// ...
}
索引映射模板(JSON格式)可以定义在配置文件中,或者通过代码动态创建。这里假设已经有一个名为my_index
的索引,并且其映射已经定义好。
4. 创建Service类实现增删改查
创建一个Service类来处理Elasticsearch的增删改查操作:
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class ElasticsearchService {@Autowiredprivate RestHighLevelClient restHighLevelClient;// 增加文档public String indexDocument(MyDocument document) throws Exception {IndexRequest request = new IndexRequest("my_index").id(document.getId()).source(new ObjectMapper().writeValueAsString(document), XContentType.JSON);IndexResponse indexResponse = restHighLevelClient.index(request, RequestOptions.DEFAULT);return indexResponse.getResult().name();}// 获取文档public MyDocument getDocument(String id) throws Exception {GetRequest request = new GetRequest("my_index", id);GetResponse getResponse = restHighLevelClient.get(request, RequestOptions.DEFAULT);if (getResponse.isExists()) {return new ObjectMapper().readValue(getResponse.getSourceAsString(), MyDocument.class);} else {return null;}}// 删除文档public String deleteDocument(String id) throws Exception {DeleteRequest request = new DeleteRequest("my_index", id);DeleteResponse deleteResponse = restHighLevelClient.delete(request, RequestOptions.DEFAULT);return deleteResponse.getResult().name();}// 更新文档public String updateDocument(String id, MyDocument document) throws Exception {UpdateRequest request = new UpdateRequest("my_index", id).doc(new ObjectMapper().writeValueAsString(document), XContentType.JSON);UpdateResponse updateResponse = restHighLevelClient.update(request, RequestOptions.DEFAULT);return updateResponse.getResult().name();}
}
注意:在实际代码中,需要使用com.fasterxml.jackson.databind.ObjectMapper
来处理JSON序列化和反序列化,因此需要添加Jackson的依赖。
5. 创建Controller类处理HTTP请求
创建一个Controller类来处理来自前端的HTTP请求,并调用Service类的方法来实现业务逻辑:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;@RestController
@RequestMapping("/elasticsearch")
public class ElasticsearchController {@Autowiredprivate ElasticsearchService elasticsearchService;@PostMapping("/index")public String indexDocument(@RequestBody MyDocument document) {try {return elasticsearchService.indexDocument(document);} catch (Exception e) {e.printStackTrace();return "Error indexing document";}}@GetMapping("/{id}")public MyDocument getDocument(@PathVariable String id) {try {return elasticsearchService.getDocument(id);} catch (Exception e) {e.printStackTrace();return null;}}@DeleteMapping("/{id}")public String deleteDocument(@PathVariable String id) {try {return elasticsearchService.deleteDocument(id);} catch (Exception e) {e.printStackTrace();return "Error deleting document";}}@PutMapping("/{id}")public String updateDocument(@PathVariable String id, @RequestBody MyDocument document) {try {return elasticsearchService.updateDocument(id, document);} catch (Exception e) {e.printStackTrace();return "Error updating document";}}
}
6. 配置文件
在application.properties
或application.yml
文件中配置Elasticsearch的相关属性(如果需要的话,但在这个示例中已经在配置类中硬编码了主机和端口):
# Elasticsearch配置(可选)
# elasticsearch.host=localhost
# elasticsearch.port=9200
7. 运行项目
确保Elasticsearch服务已经启动,并且可以通过http://localhost:9200
访问。然后运行Spring Boot项目,并通过Postman或其他HTTP客户端工具测试Elasticsearch的增删改查功能。
这个示例Demo展示了如何在Spring Boot 3.3.4项目中整合Elasticsearch 7.12.1,并实现了基本的增删改查功能。你可以根据自己的需求进行扩展和修改。