使用 Spring Boot 和 GraalVM 的原生镜像

🧑 博主简介:CSDN博客专家历代文学网(PC端可以访问:历代文学,移动端可微信小程序搜索“历代文学”)总架构师,15年工作经验,精通Java编程高并发设计Springboot和微服务,熟悉LinuxESXI虚拟化以及云原生Docker和K8s,热衷于探索科技的边界,并将理论知识转化为实际应用。保持对新技术的好奇心,乐于分享所学,希望通过我的实践经历和见解,启发他人的创新思维。在这里,我希望能与志同道合的朋友交流探讨,共同进步,一起在技术的世界里不断学习成长。
技术合作请加本人wx(注明来自csdn):foreast_sea

在这里插入图片描述


1. 概述

在本文中,我们将了解原生镜像,以及如何从 Spring Boot 应用程序和 GraalVM 的原生镜像构建器创建原生镜像。我们指的是 Spring Boot 3,但我们将在本文末尾解决与 Spring Boot 2 的差异。

2. 原生镜像

本机映像是一种将 Java 代码构建为独立可执行文件的技术。此可执行文件包括应用程序类、来自其依赖项的类、运行时库类以及来自 JDK 的静态链接本机代码。JVM 已打包到本机映像中,因此目标系统上不需要任何 Java 运行时环境,但构建工件取决于平台。因此,我们需要为每个支持的目标系统构建一个版本,当我们使用 Docker 等容器技术时,这会更容易,我们可以将容器构建为可以部署到任何 Docker 运行时的目标系统。

2.1. GraalVM 和原生镜像构建器

通用递归应用程序和算法语言虚拟机 (Graal VM) 是为 Java 和其他 JVM 语言编写的高性能 JDK 发行版,同时支持 JavaScript、Ruby、Python 和其他几种语言。它提供了一个 Native Image 构建器 – 一种从 Java 应用程序构建原生代码并将其与 VM 一起打包成独立可执行文件的工具。它由 Spring Boot Maven 和 Gradle Plugin 官方支持,但有一些例外(最糟糕的是 Mockito 目前不支持原生测试)。

2.2. 特殊功能

在构建原生镜像时,我们遇到了两个典型特征。

预先 (AOT) 编译是将高级 Java 代码编译为本机可执行代码的过程。通常,这是由 JVM 的 Just-in-time 编译器 (JIT) 在运行时完成的,它允许在执行应用程序时进行观察和优化。在 AOT 编译的情况下,此优势将丢失。

通常,在 AOT 编译之前,可以选择有一个单独的步骤,称为 AOT 处理,即从代码中收集元数据并将其提供给 AOT 编译器。划分为这两个步骤是有意义的,因为 AOT 处理可以是特定于框架的,而 AOT 编译器更通用。下图给出了一个概述:

Java 平台的另一个特点是,只需将 JAR 放入 Classpath 中,即可在目标系统上实现可扩展性。由于启动时的反射和注释扫描,我们在应用程序中获得了扩展行为。

遗憾的是,这会减慢启动时间,并且不会带来任何好处,尤其是对于云原生应用程序,其中甚至服务器运行时和 Java 基类也被打包到 JAR 中。因此,我们省去了这个功能,然后可以使用 Closed World Optimization 构建应用程序。

这两项功能都减少了运行时需要执行的工作量。

2.3. 优势

本机映像具有各种优势,例如即时启动和减少内存消耗。它们可以打包到轻量级容器映像中,以便更快、更高效地部署,并且它们减少了攻击面。

2.4. 限制

由于 Closed World Optimization,在编写应用程序代码和使用框架时,我们必须注意一些限制。不久:

  • 类初始值设定项可以在构建时执行,以实现更快的启动和更好的峰值性能。但我们必须意识到,这可能会破坏代码中的一些假设,例如,当加载一个必须在构建时可用的文件时。
  • 反射和动态代理在运行时成本高昂,因此在 Closed World 假设下在构建时进行了优化。在构建时执行时,我们可以在类初始化器中不受限制地使用它。任何其他用法都必须向 AOT 编译器公布,Native Image 构建器会尝试通过执行静态代码分析来访问该编译器。如果失败,我们必须提供此信息,例如,通过配置文件。
  • 这同样适用于所有基于反射的技术,例如 JNI 和 Serialization。
  • 此外,本机映像生成器还提供了自己的本机接口,该接口比 JNI 简单得多,开销也较低。
  • 对于本机映像构建,字节码在运行时不再可用,因此无法使用针对 JVMTI 的工具进行调试和监控。然后,我们必须使用本机调试器和监控工具。

关于 Spring Boot,我们必须意识到,运行时不再完全支持配置文件、条件 bean 和 .enable 属性等功能。如果我们使用 profiles,则必须在构建时指定它们。

3. 基本设置

在构建原生镜像之前,我们必须安装这些工具。

3.1. GraalVM 和原生镜像

首先,我们按照安装说明安装当前版本的 GraalVM 和原生映像构建器。(Spring Boot 需要 22.3 版本)我们应该确保安装目录可以通过 GRAALVM_HOME 环境变量获得,并且 “<GRAALVM_HOME>/bin” 已添加到 PATH 变量中。

3.2. 原生编译器

在构建过程中,Native Image 构建器会调用特定于平台的原生编译器。因此,我们需要这个原生编译器,按照我们平台的 “Prerequisite” 说明进行操作。这将使构建平台相关。我们必须知道,只能在特定于平台的命令行中运行构建。例如,使用 Git Bash 在 Windows 上运行构建将不起作用。我们需要改用 Windows 命令行。

3.3. Docker

作为先决条件,我们将确保安装 Docker,稍后需要运行本机映像。Spring Boot Maven 和 Gradle 插件使用 Paketo Tiny Builder 构建容器。

4. 使用 Spring Boot 配置和构建项目

将本机构建功能与 Spring Boot 一起使用非常简单。例如,通过使用 Spring Initializr 并添加应用程序代码来创建我们的项目。然后,要使用 GraalVM 的原生映像构建器构建原生映像,我们需要使用 GraalVM 本身提供的 Maven 或 Gradle 插件来扩展我们的构建。

4.1. Maven 浏览器

Spring Boot Maven 插件的目标是 AOT 处理(即,不是 AOT 编译自身,而是为 AOT 编译器收集元数据,例如,在代码中注册反射的使用)和构建可与 Docker 一起运行的 OCI 映像。我们可以直接调用这些目标:

mvn spring-boot:process-aot
mvn spring-boot:process-test-aot
mvn spring-boot:build-image

我们不需要这样做,因为 Spring Boot 父 POM 定义了一个将这些目标绑定到构建的本机配置文件。我们需要使用此激活的配置文件进行构建:

mvn clean package -Pnative

如果我们还想执行本机测试,则可以激活第二个配置文件:

mvn clean package -Pnative,nativeTest

如果我们想要构建原生镜像,就必须添加 native-maven-plugin 的相应目标。因此,我们也可以定义一个原生配置文件。因为这个插件是由父 POM 管理的,所以我们可以保留版本号:

<profiles><profile><id>native</id><build><plugins><plugin><groupId>org.graalvm.buildtools</groupId><artifactId>native-maven-plugin</artifactId><executions><execution><id>build-native</id><goals><goal>compile-no-fork</goal></goals><phase>package</phase></execution></executions></plugin></plugins></build></profile>
</profiles>

目前,本机测试执行不支持 Mockito。因此,我们可以排除 Mocking 测试,或者通过将以下内容添加到我们的 POM 中来跳过本机测试:

<build><pluginManagement><plugins><plugin><groupId>org.graalvm.buildtools</groupId><artifactId>native-maven-plugin</artifactId><configuration><skipNativeTests>true</skipNativeTests></configuration></plugin></plugins></pluginManagement>
</build>

4.2. 在没有父 POM 的情况下使用 Spring Boot

如果我们不能从 Spring Boot Parent POM 继承,而是将其用作导入范围的依赖项,则必须自己配置插件和配置文件。然后,我们必须将以下内容添加到我们的 POM 中:

<build><pluginManagement><plugins><plugin><groupId>org.graalvm.buildtools</groupId><artifactId>native-maven-plugin</artifactId><version>${native-build-tools-plugin.version}</version><extensions>true</extensions></plugin></plugins></pluginManagement>
</build>
<profiles><profile><id>native</id><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><image><builder>paketobuildpacks/builder:tiny</builder><env><BP_NATIVE_IMAGE>true</BP_NATIVE_IMAGE></env></image></configuration><executions><execution><id>process-aot</id><goals><goal>process-aot</goal></goals></execution></executions></plugin><plugin><groupId>org.graalvm.buildtools</groupId><artifactId>native-maven-plugin</artifactId><configuration><classesDirectory>${project.build.outputDirectory}</classesDirectory><metadataRepository><enabled>true</enabled></metadataRepository><requiredVersion>22.3</requiredVersion></configuration><executions><execution><id>add-reachability-metadata</id><goals><goal>add-reachability-metadata</goal></goals></execution></executions></plugin></plugins></build></profile><profile><id>nativeTest</id><dependencies><dependency><groupId>org.junit.platform</groupId><artifactId>junit-platform-launcher</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><executions><execution><id>process-test-aot</id><goals><goal>process-test-aot</goal></goals></execution></executions></plugin><plugin><groupId>org.graalvm.buildtools</groupId><artifactId>native-maven-plugin</artifactId><configuration><classesDirectory>${project.build.outputDirectory}</classesDirectory><metadataRepository><enabled>true</enabled></metadataRepository><requiredVersion>22.3</requiredVersion></configuration><executions><execution><id>native-test</id><goals><goal>test</goal></goals></execution></executions></plugin></plugins></build></profile>
</profiles>
<properties><native-build-tools-plugin.version>0.9.17</native-build-tools-plugin.version>
</properties>

4.3. 格拉德尔

Spring Boot Gradle 插件提供用于 AOT 处理的任务(即,不是 AOT 编译自身,而是为 AOT 编译器收集元数据,例如,在代码中注册反射的使用情况)和构建可与 Docker 一起运行的 OCI 映像:

gradle processAot
gradle processTestAot
gradle bootBuildImage

如果我们想构建原生镜像,我们必须添加 Gradle 插件来构建 GraalVM 原生镜像:

plugins {// ...id 'org.graalvm.buildtools.native' version '0.9.17'
}

然后,我们可以通过调用

gradle nativeTest
gradle nativeCompile

目前,本机测试执行不支持 Mockito。因此,我们可以通过配置 graalvmNative 扩展来排除 Mocking 测试或跳过原生测试,如下所示:

graalvmNative {testSupport = false
}

5. 扩展本机映像生成配置

如前所述,我们必须为 AOT 编译器注册反射、类路径扫描、动态代理等的每次用法。因为 Spring 的内置原生支持是一个非常年轻的功能,目前并不是所有的 Spring 模块都有内置支持,所以我们目前需要自己添加这个。这可以通过手动创建 build configuration 来完成。尽管如此,使用 Spring Boot 提供的接口还是更容易,这样 Maven 和 Gradle 插件都可以在 AOT 处理期间使用我们的代码来生成构建配置。

指定其他本机配置的一种可能性是 Native Hints。那么,让我们看看目前缺少的内置支持的两个示例,以及如何将其添加到我们的应用程序中以使其正常工作。

5.1. 示例:Jackson 的 PropertyNamingStrategy

在 MVC Web 应用程序中,REST 控制器方法的每个返回值都由 Jackson 序列化,并自动将每个属性命名为 JSON 元素。我们可以通过在应用程序属性文件中配置 Jackson 的 PropertyNamingStrategy 来全局影响名称映射:

spring.jacksonproperty-naming-strategy=SNAKE_CASE

SNAKE_CASE 是 PropertyNamingStrategies 类型的静态成员的名称。不幸的是,此成员通过反射解决了。因此,AOT 编译器需要知道这一点,否则,我们将收到一条错误消息:

Caused by: java.lang.IllegalArgumentException: Constant named 'SNAKE_CASE' not foundat org.springframework.util.Assert.notNull(Assert.java:219) ~[na:na]at org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration$Jackson2ObjectMapperBuilderCustomizerConfiguration$StandardJackson2ObjectMapperBuilderCustomizer.configurePropertyNamingStrategyField(JacksonAutoConfiguration.java:287) ~[spring-features.exe:na]

为此,我们可以通过如下简单的方式实现和注册 RuntimeHintsRegistrar

@Configuration
@ImportRuntimeHints(JacksonRuntimeHints.PropertyNamingStrategyRegistrar.class)
public class JacksonRuntimeHints {static class PropertyNamingStrategyRegistrar implements RuntimeHintsRegistrar {@Overridepublic void registerHints(RuntimeHints hints, ClassLoader classLoader) {try {hints.reflection().registerField(PropertyNamingStrategies.class.getDeclaredField("SNAKE_CASE"));} catch (NoSuchFieldException e) {// ...}}}}

注意:从 3.0.0-RC2 版本开始,在 Spring Boot 中解决此问题的拉取请求已经合并,因此它可以与 Spring Boot 3 一起开箱即用。

5.2. 示例:GraphQL 架构文件

如果我们想实现 GraphQL API,我们需要创建一个架构文件并将其定位在“classpath:/graphql/*.graphqls”下,Springs GraphQL 自动配置会自动检测到它。这是通过 Classpath scanning 以及集成的 GraphiQL 测试客户端的欢迎页面完成的。因此,要在本机可执行文件中正常工作,AOT 编译器需要了解这一点。我们可以用同样的方式注册它:

@ImportRuntimeHints(GraphQlRuntimeHints.GraphQlResourcesRegistrar.class)
@Configuration
public class GraphQlRuntimeHints {static class GraphQlResourcesRegistrar implements RuntimeHintsRegistrar {@Overridepublic void registerHints(RuntimeHints hints, ClassLoader classLoader) {hints.resources().registerPattern("graphql/**/").registerPattern("graphiql/index.html");}}}

Spring GraphQL 团队已经在努力解决这个问题,因此我们可能会在未来版本中内置它。

6. 编写测试

要测试 RuntimeHintsRegistrar 实现,我们甚至不需要运行 Spring Boot 测试,我们可以创建一个简单的 JUnit 测试,如下所示:

@Test
void shouldRegisterSnakeCasePropertyNamingStrategy() {// arrangefinal var hints = new RuntimeHints();final var expectSnakeCaseHint = RuntimeHintsPredicates.reflection().onField(PropertyNamingStrategies.class, "SNAKE_CASE");// actnew JacksonRuntimeHints.PropertyNamingStrategyRegistrar().registerHints(hints, getClass().getClassLoader());// assertassertThat(expectSnakeCaseHint).accepts(hints);
}

如果我们想通过集成测试来测试它,我们可以检查 Jackson ObjectMapper 是否具有正确的配置:

@SpringBootTest
class JacksonAutoConfigurationIntegrationTest {@AutowiredObjectMapper mapper;@Testvoid shouldUseSnakeCasePropertyNamingStrategy() {assertThat(mapper.getPropertyNamingStrategy()).isSameAs(PropertyNamingStrategies.SNAKE_CASE);}}

要使用 native 模式对其进行测试,我们必须运行一个 native test:

# Maven
mvn clean package -Pnative,nativeTest
# Gradle
gradle nativeTest

如果我们需要为 Spring Boot Tests 提供特定于测试的 AOT 支持,我们可以使用 AotTestExecutionListener 接口实现TestRuntimeHintsRegistrar或TestExecutionListener。我们可以在官方文档中找到详细信息。

7. Spring Boot 2

Spring 6 和 Spring Boot 3 在原生镜像构建方面迈出了一大步。但是对于之前的主要版本,这也是可能的。我们只需要知道目前还没有内置支持,即有一个补充的 Spring Native 计划来处理这个主题。因此,我们必须在我们的项目中手动包含和配置它。对于 AOT 处理,有一个单独的 Maven 和 Gradle 插件,该插件未合并到 Spring Boot 插件中。当然,集成库提供的原生支持程度不如现在(将来会更多)。

7.1. Spring 原生依赖

首先,我们必须为 Spring Native 添加 Maven 依赖项:

<dependency><groupId>org.springframework.experimental</groupId><artifactId>spring-native</artifactId><version>0.12.1</version>
</dependency>

但是,对于 Gradle 项目,Spring Native 是由 Spring AOT 插件自动添加的。

需要注意的是,每个 Spring Native 版本只支持一个特定的 Spring Boot 版本——比如 Spring Native 0.12.1 只支持 Spring Boot 2.7.1。因此,我们应该确保在pom.xml中使用兼容的 Spring Boot Maven 依赖项。

7.2. 构建包

要构建 OCI 映像,我们需要显式配置构建包。

使用 Maven,我们需要使用 Paketo Java buildpacks 的带有本机映像配置的 spring-boot-maven-plugin:

<build><pluginManagement><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><image><builder>paketobuildpacks/builder:tiny</builder><env><BP_NATIVE_IMAGE>true</BP_NATIVE_IMAGE></env></image></configuration></plugin></plugins></pluginManagement>
</build>

在这里,我们将使用各种可用构建器(如 base 和 full)中的小型构建器来构建原生镜像。此外,我们还通过向 BP_NATIVE_IMAGE 环境变量提供 true 值来启用 buildpack。

同样,在使用 Gradle 时,我们可以将 tiny 构建器以及 BP_NATIVE_IMAGE 环境变量添加到 build.gradle 文件中:

bootBuildImage {builder = "paketobuildpacks/builder:tiny"environment = ["BP_NATIVE_IMAGE" : "true"]
}

7.3. Spring AOT 插件

接下来,我们需要添加 Spring AOT 插件,该插件执行提前转换,有助于改善本机映像的占用空间和兼容性。

因此,让我们将最新的 spring-aot-maven-plugin Maven 依赖项添加到我们的 pom.xml中:

<plugin><groupId>org.springframework.experimental</groupId><artifactId>spring-aot-maven-plugin</artifactId><version>0.12.1</version><executions><execution><id>generate</id><goals><goal>generate</goal></goals></execution></executions>
</plugin>

同样,对于 Gradle 项目,我们可以在 build.gradle 文件中添加最新的 org.springframework.experimental.aot 依赖项:

plugins {id 'org.springframework.experimental.aot' version '0.10.0'
}

此外,正如我们之前提到的,这会自动将 Spring Native 依赖项添加到 Gradle 项目中。

Spring AOT 插件提供了几个选项来确定源生成。例如,removeYamlSupport 和 removeJmxSupport 等选项分别删除 Spring Boot Yaml 和 Spring Boot JMX 支持。

7.4. 构建并运行镜像

就是这样!我们已准备好使用 Maven 命令构建 Spring Boot 项目的本机映像:

$ mvn spring-boot:build-image

7.5. 原生镜像构建

接下来,我们将添加一个名为 native 的配置文件,该配置文件支持一些插件,例如 native-maven-plugin 和 spring-boot-maven-plugin:

<profiles><profile><id>native</id><build><plugins><plugin><groupId>org.graalvm.buildtools</groupId><artifactId>native-maven-plugin</artifactId><version>0.9.17</version><executions><execution><id>build-native</id><goals><goal>build</goal></goals><phase>package</phase></execution></executions></plugin><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><classifier>exec</classifier></configuration></plugin></plugins></build></profile>
</profiles>

此配置文件将在打包阶段从构建中调用 native-image 编译器。

但是,在使用 Gradle 时,我们会将最新的 org.graalvm.buildtools.native 插件添加到 build.gradle 文件中:

plugins {id 'org.graalvm.buildtools.native' version '0.9.17'
}

就是这样!我们已准备好通过在 Maven package 命令中提供本机配置文件来构建本机映像:

mvn clean package -Pnative

8. 总结

在本教程中,我们探索了使用 Spring Boot 和 GraalVM 的原生构建工具构建原生镜像。我们了解了 Spring 的内置原生支持。所有代码实现都可以在 GitHub 上找到(Spring Boot 2 示例)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/482006.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于Java Springboot宠物医院微信小程序

一、作品包含 源码数据库设计文档万字PPT全套环境和工具资源部署教程 二、项目技术 前端技术&#xff1a;Html、Css、Js、Vue、Element-ui 数据库&#xff1a;MySQL 后端技术&#xff1a;Java、Spring Boot、MyBatis 三、运行环境 开发工具&#xff1a;IDEA/eclipse 微信…

Tree搜索二叉树、map和set_数据结构

数据结构专栏 如烟花般绚烂却又稍纵即逝的个人主页 本章讲述数据结构中搜索二叉树与HashMap的学习&#xff0c;感谢大家的支持&#xff01;欢迎大家踊跃评论&#xff0c;感谢大佬们的支持! 目录 搜索二叉树的概念二叉树搜索模拟实现搜索二叉树查找搜索二叉树插入搜索二叉树删除…

C#使用ExcelDataReader读取Xlsx文件为DataTable对象

创建控制台项目 在NuGet中安装ExcelDataReader.DataSet 3.7.0 创建一个xlsx文件 测试代码 读取xlsx文件内容&#xff0c;为一个DataTable对象。 读取xlsx时&#xff0c;xlsx文件不能被其他软件打开&#xff0c;否则会报“进程无法访问此文件”的错。 using ExcelDataRead…

【JavaEE初阶】应是天仙狂醉,乱把白云揉碎 - (重点)线程

本篇博客给大家带来的是线程的知识点, 由于内容较多分几天来写. &#x1f40e;文章专栏: JavaEE初阶 &#x1f680;若有问题 评论区见 ⭐欢迎大家点赞 评论 收藏 分享 ❤❤❤ 如果你不知道分享给谁,那就分享给薯条. 你们的支持是我不断创作的动力 . 1. 认识线程 1.1 概念 )1 …

精准用户获取与私域流量运营:多商户链动 2+1 模式商城小程序的赋能策略

摘要&#xff1a;本文聚焦于精准用户对商业运营的核心价值&#xff0c;深入剖析获取精准用户的有效途径&#xff0c;特别围绕目标用户画像及出没场景展开分析。同时&#xff0c;探讨在私域流量构建进程中&#xff0c;多商户链动 21 模式商城小程序如何融入精准用户运营体系&…

Spring Boot教程之十一:获取Request 请求 和 Put请求

如何在 Spring Boot 中获取Request Body&#xff1f; Java 语言是所有编程语言中最流行的语言之一。使用 Java 编程语言有几个优点&#xff0c;无论是出于安全目的还是构建大型分发项目。使用 Java 的优点之一是 Java 试图借助类、继承、多态等概念将语言中的每个概念与现实世…

DVWA靶场文件包含(File Inclusion)通关教程(high级别)

目录 DVWA 靶场建立闯关 DVWA 靶场建立 需要的东西&#xff1a; phpStudy&#xff1a; 链接&#xff1a; phpStudy 提取码&#xff1a;0278 DVWA-master 链接&#xff1a; DVWA靶场 提取码&#xff1a;0278 建议在虚拟机中操作&#xff0c;以防数据库冲突&#xff0c;下面有…

基于yolov8、yolov5的铝材缺陷检测识别系统(含UI界面、训练好的模型、Python代码、数据集)

摘要&#xff1a;铝材缺陷检测在现代工业生产和质量管理中具有重要意义&#xff0c;不仅能帮助企业实时监控铝材质量&#xff0c;还为智能化生产系统提供了可靠的数据支撑。本文介绍了一款基于YOLOv8、YOLOv5等深度学习框架的铝材缺陷检测模型&#xff0c;该模型使用了大量包含…

力扣刷题TOP101:8.BM10 两个链表的第一个公共结点

目录&#xff1a; 目的 思路 复杂度 记忆秘诀 python代码 目的 两个无环的单向链表&#xff0c;它们的第一个公共结点{{6,7}。 思路 这个任务是找到两个链表的第一个公共结点。可以看作两个心机boy偷偷补课翻车事件。平时嘴上说自己在家玩游戏&#xff0c;实际上背地里都偷…

哪些行业对六西格玛管理方法的需求较大?

六西格玛作为一种追求极致质量和流程优化的管理哲学&#xff0c;自诞生以来&#xff0c;便在多个行业中展现出了巨大的应用价值。该方法通过定义、测量、分析、改进和控制&#xff08;DMAIC&#xff09;五个阶段&#xff0c;帮助企业实现流程的持续改进&#xff0c;提高产品质量…

Spring Web MVC其他扩展(详解下)

文章目录 Spring MVC其他扩展&#xff08;下&#xff09;异常处理异常处理机制声明式异常好处基于注解异常声明异常处理 拦截器拦截器概念拦截器使用拦截器作用位置图解拦截器案例拦截器工作原理源码 参数校验校验概述操作演示SpringMVC自定义参数验证ValueObject(VO) 文件上传…

排序学习整理(1)

1.排序的概念及运用 1.1概念 排序&#xff1a;所谓排序&#xff0c;就是使⼀串记录&#xff0c;按照其中的某个或某些关键字的大小&#xff0c;递增或递减的排列起来的操作&#xff0c;以便更容易查找、组织或分析数据。 1.2运用 购物筛选排序 院校排名 1.3常见排序算法 2.实…

【linux学习指南】Linux进程信号产生(三) 硬件异常除零出错?野指针异常?core文件

文章目录 &#x1f4dd;前言&#x1f320;模拟除0&#x1f309;除0出错&#xff1f;&#x1f309;野指针异常? &#x1f320;⼦进程退出coredump&#x1f309;Core Dump &#x1f6a9;总结 &#x1f4dd;前言 硬件异常被硬件以某种⽅式被硬件检测到并通知内核,然后内核向当前…

【人工智能-科普】图神经网络(GNN):与传统神经网络的区别与优势

文章目录 图神经网络(GNN):与传统神经网络的区别与优势什么是图神经网络?图的基本概念GNN的工作原理GNN与传统神经网络的不同1. 数据结构的不同2. 信息传递方式的不同3. 模型的可扩展性4. 局部与全局信息的结合GNN的应用领域总结图神经网络(GNN):与传统神经网络的区别与…

青藤云安全携手财信证券,入选金融科技创新应用优秀案例

11月29日&#xff0c;由中国信息通信研究院主办的第四届“金信通”金融科技创新应用案例评选结果正式发布。财信证券与青藤云安全联合提交的“基于RASP技术的API及数据链路安全治理项目”以其卓越的创新性和先进性&#xff0c;成功入选金融科技创新应用优秀案例。 据悉&#x…

Python系列 - MQTT协议

Python系列 - MQTT协议 资源连接 MQTT的介绍和应用场景的示例说明 一、什么是MQTT 百度关于MQTT的介绍如下&#xff1a; MQTT(消息队列遥测传输)是ISO 标准(ISO/IEC PRF 20922)下基于发布订阅范式的消息协议。它工作在 TCP/IP协议之上&#xff0c;是为硬件性能低下的远程设…

winform跨线程更新界面

1、报错代码 下面的代码中的this.Text指的是一个winform的窗体&#xff0c;开启Task执行下面的代码以后直接报错&#xff0c;提示线程间操作无效&#xff0c;这是因为在WinForms应用程序中&#xff0c;UI元素&#xff08;如控件&#xff09;通常只能在创建它们的线程&#xff…

Mybatis:CRUD数据操作之多条件查询及动态SQL

Mybatis基础环境准备请看&#xff1a;Mybatis基础环境准备 本篇讲解Mybati数据CRUD数据操作之多条件查询 1&#xff0c;编写接口方法 在 com.itheima.mapper 包写创建名为 BrandMapper 的接口。在 BrandMapper 接口中定义多条件查询的方法。 而该功能有三个参数&#xff0c;…

音视频技术扫盲之预测编码的基本原理探究

预测编码是一种数据压缩技术&#xff0c;广泛应用于图像、视频和音频编码等领域。其基本原理是利用数据的相关性&#xff0c;通过对当前数据的预测和实际值与预测值之间的差值进行编码&#xff0c;从而实现数据压缩的目的。 一、预测编码的基本概念 预测编码主要包括预测器和…

5. langgraph实现高级RAG (Adaptive RAG)

1. 数据准备 from langchain.text_splitter import RecursiveCharacterTextSplitter from langchain_community.document_loaders import WebBaseLoader from langchain_community.vectorstores import Chromaurls ["https://lilianweng.github.io/posts/2023-06-23-age…