在 Spring Boot 中使用 Flyway 进行数据库迁移

在之前的 Spring Boot JdbcTemplate 教程 中,我们见识了如何使用 schema.sql 和 data.sql 脚本初始化数据库。这对于演示项目可能有用,但对于实际应用,我们应该使用数据库迁移工具。 Flyway 是最流行的基于 Java 的数据库迁移工具。可以将 Flyway 作为独立库,或使用 flyway-maven-plugin 或使用 Flyway Gradle 插件进行数据库迁移。 Spring Boot 提供了开箱即用的支持,用于 Flyway 数据库迁移。让我们看看如何创建一个使用 Spring Data JPA 与 PostgreSQL 数据库交互,并使用 Flyway 实现数据库迁移的 Spring Boot 应用。 首先,访问 https://start.springboot.io/,选择 Spring Web、Spring Data JPA、PostgreSQL Driver、Flyway Migration 和 Testcontainers starter,创建 Spring Boot 应用程序。 创建 Flyway 迁移脚本 Flyway 遵循 V<VERSION>__<DESCRIPTION>.sql 命名约定来命名其版本化的迁移脚本。让我们在 src/main/resources/db/migration 文件夹下添加以下两个迁移脚本。 V1__create_tables.sql: create table bookmarks ( id bigserial not null, title varchar not null, url varchar not null, created_at timestamp, primary key (id) ); V2__create_bookmarks_indexes.

将 Spring Boot 应用构建为 War 包

Spring Boot 最具特色的功能就是使用嵌入式服务器,可以把应用构建为一个独立、可执行的 jar,这极大地方便了部署。但是仍有人希望把应用打包为 WAR 包,部署在外部的 Servlet 容器(Tomcat、Jetty 等)中运行。 本文将会指导你如何更改 Spring Boot 的打包方式为 War,并且部署到外部服务器中(Servlet 3.x +)。 Spring Boot 打包为 War 包的步骤 1、修改打包方式 <packaging>war</packaging> 修改 packaging 节点值为 war。Maven 工程默认打包方式为 jar,如果你的 pom.xml 中没有 packaging 节点,则需要手动设置。 2、修改 Servlet 容器的 scope <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope> </dependency> 由于我们会使用外部的 Tomcat,所以需要主动把嵌入式容器 spring-boot-starter-tomcat 依赖的 scope 声明为 provided,表示该依赖只用于编译、测试。 3、修改启动类,继承 SpringBootServletInitializer package cn.springdoc.demo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; @SpringBootApplication public class DemoApplication extends SpringBootServletInitializer{ public static void main(String[] args) { SpringApplication.

使用 Spring Data Redis 配置 Redis TTL

1、简介 在本教程中,我们将学习如何在 Spring Data Redis 中配置 key 的过期时间。 2、项目设置 假设我们有一个整合了 spring data redis 的 spring boot 项目,我们打算使用 redis 来管理用户的会话(Session)。 2.1、依赖 首先,在 pom.xml 中添加以下依赖: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> <version>3.0.4</version> </dependency> spring-boot-starter-data-redis 将传递依赖 spring-data-redis 和 lettuce-core。 2.2、Redis 配置 其次,添加 RedisTemplate 配置: @Configuration public class RedisConfiguration { @Bean public RedisTemplate<String, Session> getRedisTemplate(RedisConnectionFactory redisConnectionFactory) { RedisTemplate<String, Session> redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(redisConnectionFactory); return redisTemplate; } } 2.3、Model 第三,创建 Session model: @RedisHash public class Session { @Id private String id; private Long expirationInSeconds; } 2.

设置 Spring Cloud FeignClient 的目标 URL

1、简介 在本文中,我们将学习如何给 Feign Client 接口设置目标 URL。 2、概览 为了快速入门,我们将使用 JSONPlaceholder 网站中 Album(相册)、Post(帖子)和 Todo 对象的模拟响应。 Album 类如下: public class Album { private Integer id; private Integer userId; private String title; // get、set 方法省略 } Post 类如下: public class Post { private Integer id; private Integer userId; private String title; private String body; //get、set 方法省略 } Todo 类如下: public class Todo { private Integer id; private Integer userId; private String title; private Boolean completed; // get、set 方法省略 } 3、在注解中添 Base URL 我们可以在客户端接口的 @FeignClient 注解中的 url 属性中设置 base URL。然后,我们用相关 HTTP 动词注解方法,并添加所需的端点:

万剑归宗:Spring Boot 3.2、GraalVM 原生镜像、Java 21 和 Project Loom 虚拟线程

酝酿已久,我们终于可以创建使用 Spring Boot(3.2)和 Java 21 虚拟线程(Project Loom)的 GraalVM 原生镜像了! 这一切有什么意义呢?Project Loom 和 GraalVM 原生镜像各自都具有引人注目的运行时特性。我已经等了很久,终于等到了它们的融合!让我们依次唠唠。 GraalVM 原生镜像 GraalVM 是一个 OpenJDK 发行版,提供了一些额外的实用工具,其中包括一个名为 native-image 的工具,它可以对你的代码进行提前编译(AOT)。我们在这里不会详细介绍所有的实用功能,基本上它会对你的代码进行优化,去除你不需要的部分,然后将剩余的代码编译成针对特定操作系统和架构的原生代码,运行速度非常快。结果令人惊叹,类似于编译 C 或 Go 程序所得到的结果。生成的可执行文件在启动时几乎没有延迟,并且在运行时占用的内存要少得多。想象一下,能够部署现有的 Spring Boot 应用程序,并且它只占用几十兆字节的内存,并在几百毫秒内启动。现在,这是可能的。只需运行 ./gradlew nativeCompile 或 ./mvnw -Pnative native:compile,即可。自 2022 年 11 月 Spring Boot 3.0 发布以来,Spring Boot 已经支持在生产环境中使用 GraalVM 原生镜像。 Project Loom Project Loom 为 JVM 引入了透明的 Fiber(纤程,也成为协程、虚拟线程)。就目前而言,在 Java 20 或更早的版本中,IO 是阻塞的。调用 InputStream#read() 可能需要等待下一个字节的到达。在 java.io.File IO中,很少会有太多延迟。然而,在网络中,你真的无法确定。客户端可能会断开连接。客户端可能会经过一个隧道。同样,很难说。在此期间,程序流程被阻塞在执行线程上。在下面的代码片段中,我们无法知道何时会看到打印出来的单词 after。可能是从现在开始的纳秒级时间,也可能是从现在开始的一周后。它是阻塞的。 InputStream in = ... System.out.println("before"); int next = in.

在 Spring Boot 中自定义 Swagger URL

1、概览 Springfox 和 SpringDoc 这两个工具简化了 Swagger API 文档的生成和维护。 在本教程中,我们将了解如何在 Spring Boot 应用中更改 Swagger-UI URL 前缀。 2、使用 Springdoc 时更改 Swagger UI URL 前缀 首先,我们可以看看 如何使用 OpenAPI 3.0 生成 REST API 文档。 根据上述教程,我们需要添加如下 SpringDoc 的依赖: <dependency> <groupId>org.springdoc</groupId> <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId> <version>2.0.2</version> </dependency> swagger-ui 的默认 URL 是 http://localhost:8080/swagger-ui.html。 比方说,我们要增加 /myproject 前缀,接下来让我们看看自定义 swagger-UI URL 的两种方法。 2.1、application.properties 我们可以在 application.properties 文件中添加以下属性来修改 swagger-UI URL: springdoc.swagger-ui.disable-swagger-default-url=true springdoc.swagger-ui.path=/myproject 2.2、配置类 我们也可以通过配置类来实现: @Component public class SwaggerConfiguration implements ApplicationListener<ApplicationPreparedEvent> { @Override public void onApplicationEvent(final ApplicationPreparedEvent event) { ConfigurableEnvironment environment = event.

设置 Swagger 文档中的示例和描述

1、概览 在本教程中,我们将演示如何使用 Swagger 注解使我们的文档更具描述性。我们会学习如何为 API 的不同部分(如方法、参数、响应等)添加描述,以及如何添加请求/响应示例。 2、项目设置 我们将创建一个简单的 Product API,提供创建和获取 product 的方法。 要从头开始创建 REST API,我们可以按照 Spring 文档中的教程 使用 Spring Boot 创建 RESTful Web 服务。 下一步是为项目设置依赖和配置。我们可以按照 本文 中的步骤使用 Spring REST API 设置 Swagger 2 3、创建 API 创建 Product API 并检查生成的文档。 3.1、Model 定义 Product 类: public class Product implements Serializable { private long id; private String name; private String price; // 省略 get/set 构造函数 } 3.2、Controller 定义两个 API 方法: @RestController @Tag(name = "Products API") public class ProductController { @PostMapping("/products") public ResponseEntity<Void> createProduct(@RequestBody Product product) { //creation logic return new ResponseEntity<>(HttpStatus.

Spring REST Docs 与 OpenAPI 的比较

1、概览 Spring REST Docs 和 OpenAPI 3.0 是为 REST API 创建 API 文档的两种方法。 在本教程中,我们将探讨它们的相对优缺点。 2、前世今生 Spring REST Docs 是由 Spring 社区开发的一个框架,用于 为RESTful API 创建准确的文档。它采用了测试驱动的方法,文档可用 Spring MVC tests、Spring Webflux 的 WebTestClient 或 REST-Assured 形式编写。 运行测试的结果会生成 AsciiDoc 文件,可以使用 Asciidoctor 将它们组合在一起,生成描述 API 的 HTML 页面。由于它遵循 TDD 方法,Spring REST Docs 自动带来了许多优势,例如减少代码错误、减少重复工作和更快的反馈周期等。 而,OpenAPI 是一种诞生于 Swagger 2.0 的规范。截至本文撰写时,其最新版本为 3.0,并有许多已知的 实现。 与其他规范一样,OpenAPI 也为其实现制定了一些基本规则。简而言之,所有 OpenAPI 实现都应该以 JSON 或 YAML 格式的 JSON 对象生成文档。 还有 许多工具 可以接收 JSON/YAML,并输出 UI 界面来可视化和导航 API。这在验收测试时非常有用。在这里的代码示例中,我们将使用 Springdoc - 一个用于 OpenAPI 3 和 Spring Boot 的框架。

在 Spring 应用中整合 Apache Kafka 以生产、消费消息

1、概览 Apache Kafka 是一个分布式且容错的流处理系统。 在本教程中,我们将介绍 Spring 对 Kafka 的支持以及它在原生 Kafka Java 客户端 API 之上提供的抽象层。 Spring Kafka 通过 KafkaTemplate 和使用 @KafkaListener 注解的消息驱动的POJO,提供了简单且典型的 Spring template 编程模型。 2、安装和设置 要下载和安装 Kafka,请参阅 此处 的官方指南。 我们需要在 pom.xml 中添加 spring-kafka 依赖: <dependency> <groupId>org.springframework.kafka</groupId> <artifactId>spring-kafka</artifactId> <version>3.0.0</version> </dependency> 然后按如下方法配置 spring-boot-maven-plugin: <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <mainClass>com.baeldung.spring.kafka.KafkaApplication</mainClass> </configuration> </plugin> 我们的示例应用程序是 Spring Boot。 本文假定服务器使用默认配置启动,并且没有更改服务端口。 3、配置 Topic 之前,我们使用命令行工具在 Kafka 中创建主题: $ bin/kafka-topics.sh --create \ --zookeeper localhost:2181 \ --replication-factor 1 --partitions 1 \ --topic mytopic 但随着 Kafka 引入 AdminClient,我们现在可以以编程式创建 topic。

在 AWS Lambda 中运行 Spring Boot 应用

1、概览 在本教程中,我们将探讨如何使用 Serverless Application Model (SAM) 框架将 Spring Boot 应用程序部署到 AWS Lambda。 这种方法有助于将现有的 API 服务器迁移到 serverless 上。 通过这种方法,我们可以利用 AWS Lambda 的可扩展性和按执行付费的定价模式,高效、经济地运行我们的应用程序。 2、理解 Lamdba AWS Lambda 是亚马逊网络服务(AWS)提供的 serverless 计算服务。它允许我们在无需配置或管理服务器的情况下运行代码。 Lambda 函数与传统服务器的主要区别之一是,Lambda 函数由事件驱动,生命周期很短。 Lambda 函数不像服务器那样持续运行,而是只在响应特定事件时才运行,例如 API 请求、队列中的消息或上传到 S3 的文件。 我们应该注意到,lambda 在处理第一个请求时需要一定的时间来启动。这就是所谓的 “冷启动”。 如果下一个请求在短时间内出现,可以使用相同的 lambda 运行时,这被称为 “热启动”。如果同时出现多个请求,则会启动多个 Lambda 运行时。 与 Lambda 理想的毫秒级启动时间相比,Spring Boot 的启动时间相对较长,因此我们会讨论这对性能的影响。 3、项目设置 我们通过修改 pom.xml 和添加一些配置来迁移现有的 Spring Boot 项目。 Spring Boot 支持的版本有 2.2.x、2.3.x、2.4.x、2.5.x、2.6.x 和 2.7.x。 3.1、Spring Boot API 示例 我们的应用程序由一个简单的 API 组成,它可以处理对 api/v1/users 端点的任何 GET 请求: