当前位置: 首页 > news >正文

重学SpringBoot3-整合 Elasticsearch 8.x (一)客户端方式

更多SpringBoot3内容请关注我的专栏:《SpringBoot3》
期待您的点赞👍收藏⭐评论✍

这里写目录标题

  • 1. 为什么选择 Elasticsearch?
  • 2. Spring Boot 3 和 Elasticsearch 8.x 的集成概述
    • 2.1 准备工作
    • 2.2 添加依赖
  • 3. Elasticsearch 客户端配置方式
    • 3.1 使用 `RestClient` (低级客户端)
    • 3.2 官方 Java API 客户端(elasticsearch-java)
    • 3.3 Spring Data Elasticsearch 提供的 `ElasticsearchTemplate`
  • 4. 总结

Elasticsearch 8.x 提供了更丰富的数据搜索和分析功能。随着 Spring Boot 3 的发布,如何将其与Elasticsearch 8.x 版本整合,成为了开发者关注的重点。本文将详细介绍 Spring Boot 3 如何整合 Elasticsearch 8.x 以及常见的客户端配置方式,以帮助大家顺利集成和配置 Elasticsearch 服务。

1. 为什么选择 Elasticsearch?

Elasticsearch 是一个分布式、RESTful 风格的搜索引擎,以其快速的全文检索、强大的数据分析和分布式架构而备受欢迎。常用于日志分析、实时数据分析、推荐系统等场景。

2. Spring Boot 3 和 Elasticsearch 8.x 的集成概述

Spring Boot 3 中推荐使用 Spring Data Elasticsearch 提供的客户端来访问 Elasticsearch,而不再使用低层次的 Transport Client。Elasticsearch 8.x 推出后,官方推荐使用 Java REST Client 和 ElasticsearchClient,Spring Data Elasticsearch 也支持这些新的客户端。

2.1 准备工作

在开始之前,请确保已安装并启动 Elasticsearch 8.x 实例,为了演示,本人通过 1panel 快速搭建一个演示版本的 ElasticSearch 8.x 版本。

image-20241103101755835

默认用户名:elastic

image-20241103102214279

2.2 添加依赖

pom.xml 文件中添加 Spring Data Elasticsearch 以及 Elasticsearch 客户端的依赖项:

image-20241103110103468

3. Elasticsearch 客户端配置方式

在 Spring Boot 3 中有几种方式可以连接 Elasticsearch 8.x。以下是常用的几种配置方式:

  • 官方低级别的 REST 客户端(low-level REST client);
  • 官方的Java API客户端 ElasticsearchClient ;
  • Spring Data Elasticsearch 提供的 ReactiveElasticsearchClient;
  • Java High Level REST Client ,7.15.0 版本废弃;
  • Java Transport Client 7.0.0 版本废弃。

3.1 使用 RestClient (低级客户端)

RestClient 是 Elasticsearch 官方提供的低级 REST 客户端,它更灵活,但需要手动处理请求和响应的序列化。对于不需要处理复杂业务逻辑的场景,可以选择这种方式。

官方教程:https://www.elastic.co/guide/en/elasticsearch/client/java-api-client/current/java-rest-low.html

依赖

        <!-- 官方低级别 REST 客户端(Low-Level REST Client) --><dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-client</artifactId><version>8.15.3</version></dependency>

特点

  • 提供直接与 Elasticsearch 进行 HTTP 请求交互的接口。
  • 适用于对请求和响应结构有细粒度控制的场景,适合自定义复杂的请求。
  • 需要手动处理序列化和反序列化。

适用场景

当需要直接控制 HTTP 请求或需要编写自定义查询时,低级别 REST 客户端是不错的选择。它适用于高灵活性和精确控制的需求场景。

配置示例

默认配置可以直接使用配置文件:

spring:elasticsearch:uris: "http://localhost:9200"socket-timeout: "10s"username: "user"password: "secret"

更详细的配置可以添加配置类进行设置:

import org.elasticsearch.client.RestClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class ElasticsearchConfig {@Beanpublic RestClient restClient() {return RestClient.builder(new HttpHost("localhost", 9200, "http")).build();}
}

使用示例

在 Service 层中,通过 RestClient 来操作 Elasticsearch:

package com.coderjia.boot318es.service;import jakarta.annotation.Resource;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.util.EntityUtils;
import org.elasticsearch.client.Request;
import org.elasticsearch.client.Response;
import org.elasticsearch.client.RestClient;
import org.springframework.stereotype.Service;/*** @author CoderJia* @create 2024/11/3 上午 11:28* @Description**/
@Service
public class MyElasticsearchService {@Resourceprivate RestClient restClient;public void addDocument(String index, String id, String jsonContent) throws Exception {Request request = new Request("PUT", "/" + index + "/_doc/" + id);request.setEntity(new StringEntity(jsonContent, ContentType.APPLICATION_JSON));restClient.performRequest(request);}public String getDocument(String index, String id) throws Exception {Request request = new Request("GET", "/" + index + "/_doc/" + id);Response response = restClient.performRequest(request);return EntityUtils.toString(response.getEntity());}public void updateDocument(String index, String id, String jsonContent) throws Exception {Request request = new Request("POST", "/" + index + "/_update/" + id);StringEntity entity = new StringEntity("{\"doc\":" + jsonContent + "}", ContentType.APPLICATION_JSON);request.setEntity(entity);restClient.performRequest(request);}public void deleteDocument(String index, String id) throws Exception {Request request = new Request("DELETE", "/" + index + "/_doc/" + id);restClient.performRequest(request);}
}

结果:

restClient执行结果

3.2 官方 Java API 客户端(elasticsearch-java)

官方推荐的 Java 和 ES 8.x 交互方式。

官方教程:https://www.elastic.co/guide/en/elasticsearch/client/java-api-client/current/index.html

依赖

        <!-- 官方 Java API 客户端 --><dependency><groupId>co.elastic.clients</groupId><artifactId>elasticsearch-java</artifactId><version>8.15.3</version></dependency><!--JSON对象映射库--><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.17.0</version></dependency>

特点

  • 这是 Elasticsearch 官方推荐的高层次客户端,提供对 Elasticsearch API 的完整封装。
  • 自动处理序列化和反序列化,支持更简洁的代码。
  • 兼容 Java 8+,适用于最新的 Spring Boot 3 和 Elasticsearch 8.x 版本。

适用场景:当希望高效地集成 Elasticsearch API 并且减少对请求响应的手动处理时,该客户端是最优选择,尤其适合数据处理或搜索的微服务。

配置示例

默认配置可以直接使用配置文件:

spring:elasticsearch:uris: "http://localhost:9200"socket-timeout: "10s"username: "user"password: "secret"

更详细的配置可以添加配置类进行设置:

package com.coderjia.boot318es.config;import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.json.jackson.JacksonJsonpMapper;
import co.elastic.clients.transport.rest_client.RestClientTransport;
import jakarta.annotation.Resource;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.elasticsearch.client.RestClient;
import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchProperties;
import org.springframework.context.annotation.Bean;/*** @author CoderJia* @create 2024/11/3 下午 02:31* @Description**/
public class ElasticsearchClientConfig {@Resourceprivate ElasticsearchProperties elasticsearchProperties;@Beanpublic ElasticsearchClient elasticsearchClient() {final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(elasticsearchProperties.getUsername(), elasticsearchProperties.getPassword()));RestClient restClient = RestClient.builder(HttpHost.create(elasticsearchProperties.getUris().get(0))).setHttpClientConfigCallback(httpClientBuilder -> httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider)).build();RestClientTransport transport = new RestClientTransport(restClient, new JacksonJsonpMapper());return new ElasticsearchClient(transport);}
}

使用示例

在 Service 层中,通过 RestClient 来操作 Elasticsearch:

package com.coderjia.boot318es.service;import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch.core.DeleteResponse;
import co.elastic.clients.elasticsearch.core.GetResponse;
import co.elastic.clients.elasticsearch.core.IndexResponse;
import co.elastic.clients.elasticsearch.core.UpdateResponse;
import com.coderjia.boot318es.User;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;import java.io.IOException;/*** @author CoderJia* @create 2024/11/3 下午 02:47* @Description**/
@Service
public class ElasticsearchClientService {@Resourceprivate ElasticsearchClient esClient;public String addDocument(String index,  User user) throws IOException {IndexResponse response = esClient.index(i -> i.index(index).id(user.getId().toString()).document(user));System.out.println("Indexed with version " + response.version());return response.id();}public User getDocument(String index, String id) throws IOException {GetResponse<User> response = esClient.get(g -> g.index(index).id(id), User.class);if (response.found()) {return response.source();} else {return null;}}public void updateDocument(String index, User user) throws IOException {UpdateResponse<User> response = esClient.update(u -> u.index(index).id(user.getId().toString()).doc(user)  // 用于更新已存在文档的字段.upsert(user), // 如果文档不存在,则插入User.class);System.out.println("Updated with version " + response.version());}public void deleteDocument(String index, String id) throws IOException {DeleteResponse response = esClient.delete(d -> d.index(index).id(id));System.out.println("Deleted with version " + response.version());}
}

结果

ElasticsearchClient执行结果

3.3 Spring Data Elasticsearch 提供的 ElasticsearchTemplate

Spring Data Elasticsearch 提供了 ElasticsearchTemplate 作为 Elasticsearch 的操作模板,ElasticsearchTemplate 提供了许多高层次的 API,简化了与 Elasticsearch 的交互,用户无需直接编写复杂的 Elasticsearch 查询。

依赖

        <!-- Spring Data Elasticsearch 提供的 ElasticsearchClient --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch</artifactId></dependency>

特点

  • 简化的操作ElasticsearchTemplate 提供了许多高层次的 API,简化了与 Elasticsearch 的交互,用户无需直接编写复杂的 Elasticsearch 查询。
  • 对象映射ElasticsearchTemplate 支持将 Java 对象映射到 Elasticsearch 文档,方便在应用程序中操作对象而无需手动处理 JSON。

配置示例

application.yml 中配置 Elasticsearch 连接地址:

spring:elasticsearch:uris: "http://localhost:9200"socket-timeout: "10s"username: "user"password: "secret"

使用示例

下面是使用 ElasticsearchTemplate 实现增、删、改、查的简单示例。

数据模型

创建一个简单的文档模型类,用于存储在 Elasticsearch 索引中的数据。

import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;@Document(indexName = "products")
public class Product {@Idprivate String id;private String name;private String description;private double price;// Getters and Setters
}

使用示例

在 Service 层中使用 Repository 来完成数据存储和查询:

package com.coderjia.boot318es.service;import com.coderjia.boot318es.bean.Product;
import jakarta.annotation.Resource;
import org.springframework.data.elasticsearch.client.elc.ElasticsearchTemplate;
import org.springframework.stereotype.Service;/*** @author CoderJia* @create 2024/11/3 下午 04:58* @Description**/
@Service
public class EsTemplateService {@Resourceprivate ElasticsearchTemplate elasticsearchTemplate;public Product saveProduct(Product product) {return elasticsearchTemplate.save(product);}public Product getProductById(String id) {return elasticsearchTemplate.get(id, Product.class);}public Product updateProduct(Product Product) {return elasticsearchTemplate.save(Product);}public void deleteProduct(String id) {elasticsearchTemplate.delete(id, Product.class);}
}

结果

ElasticsearchTemplate结果

4. 总结

在 Spring Boot 3 中集成 Elasticsearch 8.x 可以通过多种方式实现,包括 RestClientElasticsearchClientElasticsearchTemplate 等不同的客户端方案。本文提供了多种整合方式的详细示例,让您能够根据需求选择合适的集成方式。希望本文能帮助您在实际项目中顺利使用 Elasticsearch 进行高效的数据存储和查询。

后面会继续介绍 Spring Data Elasticsearch Repository 的使用,像 JPA Repository 一样操作 ES,以及 ES 各种其他使用功能,敬请期待!

相关文章:

重学SpringBoot3-整合 Elasticsearch 8.x (一)客户端方式

更多SpringBoot3内容请关注我的专栏&#xff1a;《SpringBoot3》 期待您的点赞&#x1f44d;收藏⭐评论✍ 这里写目录标题 1. 为什么选择 Elasticsearch&#xff1f;2. Spring Boot 3 和 Elasticsearch 8.x 的集成概述2.1 准备工作2.2 添加依赖 3. Elasticsearch 客户端配置方式…...

极简实现酷炫动效:Flutter隐式动画指南第三篇自定义Flutter隐式动画

目录 前言 一、TweenAnimationBuilder 二、使用TweenAnimationBuilder实现的一些动画效果 1.调整透明度的动画 2.稍微复杂点的组合动画 3.数字跳动的动画效果 前言 上两节博客分别介绍了Flutter中的隐式动画的基础知识以及使用隐式动画实现的一些动画效果。当系统提供的隐…...

无人机维护保养、部件修理更换技术详解

无人机作为一种精密的航空设备&#xff0c;其维护保养和部件修理更换是确保飞行安全、延长使用寿命的重要环节。以下是对无人机维护保养、部件修理更换技术的详细解析&#xff1a; 一、无人机维护保养技术 1. 基础构造理解&#xff1a; 熟悉无人机的基本构造&#xff0c;包括…...

xilinx vitis 更换硬件平台——ZYNQ学习笔记5

1、重新生成硬件信息 2、选择带有bit信息 3、设施路径和名字 4、打开更新硬件选项 5、选择新的硬件信息 6、打开系统工程界面 7、复位硬件信息 更新完毕...

vscode makfile编译c程序

编译工具安装 为了在 Windows 上安装 GCC&#xff0c;您需要安装 MinGW-w64。 MinGW-w64 是一个开源项目&#xff0c;它为 Windows 系统提供了一个完整的 GCC 工具链&#xff0c;支持编译生成 32 位和 64 位的 Windows 应用程序。 1. 下载MinGW-w64源代码&#xff0c;如图点…...

【学术论文投稿】探索嵌入式硬件设计:揭秘智能设备的心脏

【IEEE出版】第六届国际科技创新学术交流大会暨通信、信息系统与软件工程学术会议&#xff08;CISSE 2024&#xff09;_艾思科蓝_学术一站式服务平台 更多学术会议论文投稿请看&#xff1a;https://ais.cn/u/nuyAF3 目录 引言 嵌入式系统简介 嵌入式硬件设计的组成部分 设…...

JavaScript 概述

### JavaScript 概述 JavaScript 是一种广泛使用的编程语言&#xff0c;它最初由 Netscape 公司的 Brendan Eich 在1995年创建&#xff0c;目的是为网页添加交互性。随着时间的发展&#xff0c;JavaScript 已经从一个简单的脚本语言演变成了一种功能强大的编程语言&#xff0c;…...

2024年10月个人工作生活总结

本文为 2024年10月工作生活总结。 研发编码 一个证书过期问题记录 某天&#xff0c;现场反馈某服务无法使用问题&#xff0c;经同事排查&#xff0c;是因为服务证书过期导致的。原来&#xff0c;证书的有效期设置为5年&#xff0c;这个月刚好到期。 虽然这个问题与自己无直接…...

uniapp ,微信小程序,滚动(下滑,上拉)到底部加载下一页内容

前言 小程序的内容基本都是滑动到底部加载下一页&#xff0c;这个一般都没有什么好用的组件来用&#xff0c;我看vant和uniapp的插件里最多只有个分页&#xff0c;没有滚动到底部加载下一页。再次做个记录。 效果预览 下滑到底部若是有下一页&#xff0c;则会自动加载下一页&…...

MySQL中的日志类型有哪些?binlog、redolog和undolog的作用和区别是什么?

简介&#xff1a; MySQL中有六种日志文件&#xff0c;分别是&#xff1a;重做日志&#xff08;redo log&#xff09;、回滚日志&#xff08;undo log&#xff09;、二进制日志&#xff08;binlog&#xff09;、错误日志&#xff08;errorlog&#xff09;、慢查询日志&#xff0…...

【uni-app】创建自定义模板

1. 步骤 打开自定义模板文件夹 在此文件夹下创建模板文件&#xff08;注意后缀名&#xff09; 重新点击“新建页面” 即可看到新建的模板 2. 注意事项 创建的模板必须文件类型对应&#xff08;vue模板就创建*.vue文件, uvue模板就创建*.uvue文件&#xff09;...

Cesium移动Primitive位置

与传统的Entity实体不同&#xff0c;Primitive作为一种自定义基本图元&#xff0c;几何形状、材质和其他属性均由使用者定义&#xff0c;在需要绘制大量静态几何图形的高效渲染场景中更为适用。 Primitive的移动涉及到矩阵变换&#xff0c;并不像Entity那样给它替换一个新的坐…...

安卓13默认连接wifi热点 android13默认连接wifi

总纲 android13 rom 开发总纲说明 文章目录 1.前言2.问题分析3.代码分析4.代码修改5.编译6.彩蛋1.前言 有时候我们需要让固件里面内置好,相关的wifi的ssid和密码,让固件起来就可以连接wifi,不用在手动操作。 2.问题分析 这个功能,使用普通的安卓代码就可以实现了。 3.代…...

parted 磁盘分区

目录 磁盘格式磁盘分区文件系统挂载使用扩展 - parted、fdisk、gdisk 区别 磁盘格式 parted /dev/vdcmklabel gpt # 设置磁盘格式为GPT p # 打印磁盘信息此时磁盘格式设置完成&#xff01; 磁盘分区 开始分区&#xff1a; mkpart data_mysql # 分区名&…...

第三百零八节 Log4j教程 - Log4j日志到数据库

Log4j教程 - Log4j日志到数据库 我们可以使用log4j API通过使用org.apache.log4j.jdbc.JDBCAppender对象将信息记录到数据库中。 下表列出了JDBCAppender的配置属性。 属性描述bufferSize设置缓冲区大小。默认大小为1。driverJDBC驱动程序类。默认为sun.jdbc.odbc.JdbcOdbcDr…...

ai智能语音电销机器人可以做哪些事情?

AI智能语音电销机器人是结合人工智能技术进行自动化电话销售和客户互动的工具&#xff0c;能够完成一系列任务&#xff0c;有助于提升销售效果、优化客户体验和提高工作效率。以下是AI智能语音电销机器人可以做的一些主要事情&#xff1a; 1. 自动拨号 AI语音电销机器人可以自…...

CleanShot X - Mac(苹果电脑)专业截图录屏软件

CleanShot X 不仅提供了基础的截图功能&#xff0c;更内置了强大的图片编辑器&#xff0c;让你能轻松添加标注、形状、文本……以及将多个截图进行合并。 无论是为社交媒体制作图文&#xff0c;还是制作专业的产品 / 教程演示&#xff0c;CleanShot X 都能满足你的需求。 软件…...

Kafka 客户端工具使用分享【offsetexplorer】

前言&#xff1a; 前面我们使用 Spring Boot 继承 Kafka 完成了消息发送&#xff0c;有朋友会问 Kafka 有没有好用的客户端工具&#xff0c;RabbitMQ、RocketMQ 都有自己的管理端&#xff0c;那 Kafka 如何去查看发送出去的消息呢&#xff1f; 本篇我们就来分享一个好用的工具…...

uni-app 下拉刷新、 上拉触底(列表信息)、 上滑加载(短视频) 一键搞定

一、下拉刷新 1. 首先找到pages.json中 给需要进行下拉刷新的页面设置可以下拉刷新 2. 然后在需要实现下拉刷新的script标签内添加 导入onPullDownRefresh import {onPullDownRefresh} from dcloudio/uni-app 下拉刷新触发的事件 onPullDownRefresh(()> {console.log(正…...

基于Spring Boot+Vue的助农销售平台(协同过滤算法、限流算法、支付宝沙盒支付、实时聊天、图形化分析)

&#x1f388;系统亮点&#xff1a;协同过滤算法、节流算法、支付宝沙盒支付、图形化分析、实时聊天&#xff1b; 一.系统开发工具与环境搭建 1.系统设计开发工具 后端使用Java编程语言的Spring boot框架 项目架构&#xff1a;B/S架构 运行环境&#xff1a;win10/win11、jdk1…...

如何在Linux环境中的Qt项目中使用ActiveMQ-CPP

文章目录 代码1&#xff1a;消费者代码2&#xff1a;生成者 之前在Linux下的qt程序中使用activeMQ的时候也是用了很多时间去研究&#xff0c;本来想的是好好记录一下&#xff0c;但是当时顾着写代码。很多细节也不想再去走一遍了。大概写一下怎么使用就行了。注意&#xff1a;一…...

HTML字符实体详解

HTML 字符实体是在 HTML 文档中用来表示特定字符的特殊编码。这些字符可能因为直接输入而引发解析错误,或某些字符在 HTML 中具有特殊含义(例如,< 和 > 用于标签)。因此,使用字符实体可以确保文本的准确呈现。 1. 什么是字符实体? 字符实体由一个 & 符号开始,…...

Netty学习——NIO基础与IO模型

导学 Socket和NIO的区别 Socket和NIO是Java中用于网络编程的两个不同的API&#xff0c;具有不同的设计理念和用途。以下是它们的主要区别&#xff1a; 1. 定义 Socket: Socket是Java中用于实现网络通信的传统API&#xff0c;通常被称为Java I/O&#xff08;输入/输出&#…...

ZYNQ7045之YOLO部署——FPGA-ZYNQ Soc实战笔记1

一、简介 1、目标检测概念 2、目标检测应用 3、目标检测发展历程 二、YOLO V1 1、输入 必须为448x448分辨率 2、网络结构 卷积 池化 卷积 池化 3、输出 最终7x7x30表示&#xff0c;7x7个各自&#xff0c;每个格子有30个数据&#xff0c;30个数据包含两个部分 1&#xff1a;…...

Spring中的资源以及分类

Spring中的资源都被封装成 Resource 对象 以上是我测试代码的项目编译后的目录结构&#xff0c;target 所在的目录是 D:\\IdeaProjects\\study-spring\\ public void printStream(InputStream inputStream) throws IOException {Reader reader new InputStreamReader(input…...

初步认识Java,及使用

JAVA 特点 简单性 面向对象 分布式 健壮性 安全性 体系结构中立&#xff08;平台无关&#xff09; 可移植性 解释执行 高性能 多线程 动态 发展史 JDK&#xff0c;Eclipse下载&#xff0c;…...

C,C++被static标记的变量和函数分别是什么意思

被static关键字标记的变量和函数的含义 在C中&#xff0c;static关键字可以用于变量和函数的声明&#xff0c;它具有不同的语义和用途&#xff1a;static变量 1.全局静态变量&#xff1a;当全局变量被声明为static时&#xff0c;其作用域被限制为声明它的文件&#xff0c;即使使…...

Map 不常用方法介绍

getOrDefault 尝试获取key对应的值&#xff0c;如果未获取到&#xff0c;就返回默认值。 例子&#xff1a; private static void testGetOrDefault() {Map<String, String> map new HashMap<>(4);map.put("123", "123");String key "…...

论文翻译:ICLR 2024.DETECTING PRETRAINING DATA FROM LARGE LANGUAGE MODELS

文章目录 检测大型语言模型的预训练数据摘要1 引言2 预训练数据检测问题2.1 问题定义和挑战2.2 WIKIMIA&#xff1a;动态评估基准 3 MIN-K% PROB&#xff1a;简单的无参考预训练数据检测方法4 实验4.1 数据集和指标4.2 基线检测方法4.3 实现和结果4.4 分析 5 案例研究&#xff…...

Spring 框架精髓:从基础到分布式架构的进阶之路

一、概述 &#xff08;一&#xff09;Spring框架概念 1.概念&#xff1a; Spring框架是一个用于简化Java企业级应用开发的开源应用程序框架。 2.Spring框架的核心与提供的技术支持&#xff1a; 核心&#xff1a; IoC控制反转|反转控制&#xff1a;利用框架创建类的对象的…...