spring-boot

Spring Boot 整合 Redisson

Redisson 是一个功能十分强大的 Redis Java 客户端,它提供了丰富的功能和API,支持同步和异步操作,以及 RxJava 和响应式编程模型。Redisson 提供了50多个基于 Redis 的 Java 对象和服务,包括 分布式锁、原子计数器、分布式集合(Set、Map、List、Queue) 等高级功能。它还还支持本地缓存和 RPC 调用等功能,是开发分布式应用和使用 Redis 的理想选择。 总之,Redisson 所提供的功能已经远远超出了一个 Redis 客户端的范畴,Redis 官方也 推挤使用它 作为 Java 的 Redis 客户端。 之前我们介绍过 如何在 Spring Boot 中整合、使用 Redis。我们用到了 Spring Data Redis 组件,这是由 Spring 提供的抽象,可以使用 Jedis、Lettuce 等客户端作为实现。 Redisson 官方提供了一个 redisson-spring-boot-starter 组件,它正是 Spring Data Redis 抽象的实现,也就是说,我们可以直接使用 redisson-spring-boot-starter 无缝替换 spring-boot-starter-data-redis。 本文将会带你了解如何在 Spring Boot 中通过 redisson-spring-boot-starter 整合、使用 Redisson。 整合 Redisson 添加依赖 添加 redisson-spring-boot-starter 依赖即可。 <!-- https://mvnrepository.com/artifact/org.redisson/redisson-spring-boot-starter --> <dependency> <groupId>org.

在 Spring Boot 中整合、使用 Redis

Redis 是一款开源的,使用 C 开发的高性能内存 Key/Value 数据库,支持 String、Set、Hash、List、Stream 等等数据类型。它被广泛用于缓存、消息队列、实时分析、计数器和排行榜等场景。基本上是当代应用中必不可少的软件! Spring Boot 对 Redis 提供了开箱即用的组件:spring-boot-starter-data-redis。通过这个 starter,我们只需要几行简单的配置就可以快速地在 Spring Boot 中整合、使用 Redis。 Spring Boot 整合 Redis Maven 依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> </dependency> 除了 spring-boot-starter-data-redis 外,还添加了 commons-pool2 依赖,是因为我们需要使用到连接池。 配置属性 只需要在 application.yaml | properties 中配置如下常用的基本属性即可: spring: data: redis: # 连接地址 host: "localhost" # 端口 port: 6379 # 数据库 database: 0 # 用户名,如果有 # username: # 密码,如果有 # password: # 连接超时 connect-timeout: 5s # 读超时 timeout: 5s # Lettuce 客户端的配置 lettuce: # 连接池配置 pool: # 最小空闲连接 min-idle: 0 # 最大空闲连接 max-idle: 8 # 最大活跃连接 max-active: 8 # 从连接池获取连接 最大超时时间,小于等于0则表示不会超时 max-wait: -1ms 注意,如果你使用的是 spring boot 2.

在 Spring Boot 中使用 AOP 和 SpEL 记录操作日志

通常,我们在 Spring Boot 应用中都是用过 AOP 和自定义注解的方式来记录请求日志、操作日志等。 这种方式记录到的日志数据,都是固定的模板数据。如:XXX 删除了用户、XXX 新增了用户、XXX 查询了用户列表 等等。 如果我们想要在日志内容中添加更多的业务信息,如:XXX 删除了用户 ID = xxx 的记录,那么可以通过使用 AOP 和 SpEL 表达式来实现。 SpEL 表达式简介 SpEL(Spring Expression Language) 是 Spring 中的表达式语言,用于在运行时评估和处理表达式。它提供了一种灵活的方式来访问和操作对象的属性、方法和其他表达式。SpEL可以用于配置文件、注解、XML 配置等多种场景,用于实现动态的、可配置的行为。它支持常见的表达式操作,如算术运算、逻辑运算、条件判断、集合操作等,并且可以与 Spring 框架的其他功能整合使用。 通俗理解就是,可以在 Spring 应用中使用 String 定义表达式,在表达式中可以创建、定义对象。以及访问对象的属性、方法,进行逻辑运算等等。最后得到表达式的输出结果! 一个简单的例子如下: import org.springframework.expression.Expression; import org.springframework.expression.ExpressionParser; import org.springframework.expression.EvaluationContext; import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.expression.spel.support.StandardEvaluationContext; public class Main { public static void main(String[] args) { // 执行上下文 EvaluationContext context = new StandardEvaluationContext(); context.setVariable("param", "World"); // 设置参数到上下文 // 解析器 ExpressionParser parser = new SpelExpressionParser(); // 使用解析器,解析 SpEL 表达式 // 该表达式中定义了字符串 'Hello ' 常量,并且调用它的 .

Spring Boot 接收数组参数

普通的数组 定义一个简单的 Controller,它接收一个 String[] 类型的数组参数,如下: @RestController @RequestMapping("/demo") public class DemoController { @GetMapping public Object demo (@RequestParam("hobby") String[] hobby) { return hobby; } } Spring Boot 可以直接把以逗号分割的参数封装为集合、数组,例如: $ curl "localhost:8080/demo?hobby=chang,tiao,rap" ["chang","tiao","rap"] 其他框架、程序不一定会根据逗号进行分割。更优雅的方式,也是通用的方式应该是多次声明同名参数,例如: $ curl "localhost:8080/demo?hobby=chang&hobby=tiao&hobby=rap" ["chang","tiao","rap"] 数组也可以替换为 Collection 接口,Spring 都会正确地处理。特别是在一些需要对数组参数去重的场景,推荐使用 Set 作为参数,如下: @GetMapping public Object demo (@RequestParam("hobby") Set<String> hobby) { return hobby; } 发起请求,这一次 rap 值重复传递了 3 次: $ "localhost:8080/demo?hobby=chang&hobby=tiao&hobby=rap&hobby=rap&hobby=rap" ["chang","tiao","rap"] 得益于 Set 自带去重的特性,所以最终 hobby 集合中重复的 rap 值,只保留了一个。 使用 Set 作为参数的时候,默认使用的实现是 java.

JdbcTemplate 中废弃的 query(...) 和 queryForObject(...) 方法

1、概览 在 Spring Boot 2.4.x 以后,JdbcTemplate 中有几个方法注解了 @Deprecated,也就是说被废弃了: query(String sql, @Nullable Object[] args, ResultSetExtractor<T> rse) query(String sql, @Nullable Object[] args, RowCallbackHandler rch) query(String sql, @Nullable Object[] args, RowMapper<T> rowMapper) queryForObject(String sql, @Nullable Object[] args, RowMapper<T> rowMapper); queryForObject(String sql, @Nullable Object[] args, Class<T> requiredType) queryForList(String sql, @Nullable Object[] args, Class<T> elementType) 这些过时的方法都使用对象数组 Object[] args 传递参数。 JdbcTemplate 又提供了一些新的方法来代替它们,新方法使用了 “可变参数”,即 Varargs 传递参数。 本文接下来会讲解一下新旧方法的用法和区别。 2、数据库 使用 H2 内存数据库进行演示,假如我们有一张 student 表,如下: CREATE TABLE student ( student_id INT AUTO_INCREMENT PRIMARY KEY, student_name VARCHAR(255) NOT NULL, age INT, grade INT NOT NULL, gender VARCHAR(10) NOT NULL, state VARCHAR(100) NOT NULL ); -- Student 1 INSERT INTO student (student_name, age, grade, gender, state) VALUES ('John Smith', 18, 3, 'Male', 'California'); -- Student 2 INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Emily Johnson', 17, 2, 'Female', 'New York'); -- 其他 insert 语句 .

Spring Boot v3.1.4 发布

⭐ 新特性 在 JavaVersion 枚举中添加 TWENTY_ONE #37364 🐞 Bug 修复 当 SLF4J 和 Logback 在多线程中并行初始化时,由于 SubstituteLoggerFactory 被认为是一个竞争的 LoggerFactory 实现,启动可能会失败 #37484 使用 metadata-url 时,Saml2RelyingPartyAutoConfiguration 会忽略 sign-request #37482 在 DomainSocket 工具中泄漏文件描述符/套接字 #37460 在 WelcomePageHandlerMapping 中,无效的 Accept 头会产生 HTTP 500 #37457 PrivateKeyParser 不支持 ed448、XDH 和 RSA-PSS 密钥 #37422 使用 Gradle 8.3 并配置 Java 工具链语言版本时,“languageVersion is final and cannot be changed” #37380 当 @ConfigurationProperties 注解的记录有多个构造函数时,AOT 处理失败 #37336 使用 Gradle 和 dependency management 插件时,Spring Boot dependency management 对 ehcache 无效 #37270 SslStoreBundle 实现不是不可变的 #37222 解析因使用大写字母而无效的 OCI image 名称的速度非常慢 #37183 生成和消费不同的跟踪传播格式不起作用 #37178 使用除 secp384r1 之外的椭圆曲线时,使用 https 失败 #37169 在 3.

Spring Boot 整合 Freemarker 模板引擎

在前后端分离架构大行其道的今天,模板引擎依然有着重要的地位和不可代替性。 Freemarker 是一款界开源的老牌模板引擎,使用 Java 开发,Spring 官方对 Freemarker 提供了支持。本文将会带你学习如何在 Spring Boot 中整合 Freemarker。 创建项目 在 pom.xml 添加 spring-boot-starter-web 和 spring-boot-starter-freemarker 依赖。 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-freemarker</artifactId> </dependency> 编写模板 根据 Spring Boot 约定,模板文件应该放在 src/main/resources 目录下的 templates 目录中。 在 templates 目录中,创建 index 文件夹,用于存放渲染主页的 index.ftl 模板视图,如下: 其中 index.ftl 内容如下: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Freemarker</title> </head> <body> Hello ${title}! </body> </html> 如上,模板只是简单地输出了 Model 中的 title 属性。 配置属性 Spring Boot 提供了很多配置属性,可用于在 application.yaml | properties 中定制 Freemarker。 这些属性都以 spring.

Spring Boot 中 SSL Bundle 的用法

1、简介 以前在 Spring Boot 中配置 SSL 非常复杂,主要是证书有很多类型,如:JKS、PKCS #12 或 PEM。每种类型的配置方式又不一样。 幸运的是,Spring Boot 3.1 引入了 SSL Bundle,旨在简化 Spring Boot 中的 SSL 配置。在本教程中,我们将了解什么是 SSL Bundle,以及如何用它简化 Spring Boot 应用中的 SSL 配置。 2、Spring Boot SSL Bundle 通常,我们需要把 SSL 证书转换为可用的 Java 对象。 java.security.KeyStore 对象用于存储证书。 javax.net.ssl.KeyManager 对象用于管理密钥。 javax.net.ssl.SSLContext 对象用于创建安全的套接字连接(Socket Connection)。 每个类都需要更深入的理解和配置,使得整个过程变得繁琐且容易出错。各种 Spring Boot 组件可能还需要深入到不同的抽象层来应用这些设置,给任务增加了另一个难度层级。 SSL Bundle 将所有 SSL 的配置(如 Keystore、证书和私钥)封装成一个易于管理的单元。可以应用于一个或多个网络连接,无论它们是传入连接(嵌入式服务器)还是传出连接(HTTP 客户端)。 SSL Bundle 在 application.yaml 或 application.properties 中,配置属性前缀是 spring.ssl.bundle。 首先从 JKS Bundle 开始,使用 spring.ssl.bundle.jks 来配置 Java Keystore 证书:

在 Spring Boot 中快速处理 CORS 跨域

跨域问题每个人都会遇到,特别是在前后端分离的系统中。 如果你正在使用 Spring Boot 开发后端应用,并且浏览器中遇到了跨域问题。类似于如下: Access to fetch at 'http://127.0.0.1/demo' from origin 'https://springdoc.cn' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled. 但是你又不想去了解跨域、CORS 这些到底是个啥,你只想快速地解决这个问题。 那你可以把如下配置类,添加到你的 Spring Boot 应用中,它可以解决 99% 以上的跨域问题: // TODO package 声明 import java.time.Duration; import java.util.Arrays; import java.util.stream.Stream; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.

获取 Spring Boot 应用的 PID

PID 是进程标识符(Process Identifier)的缩写。在操作系统中,每个运行的进程都被分配一个唯一的 PID,用于标识进程。PID 通常是一个整数值,可以用来跟踪和管理进程的状态、资源分配以及进程间的通信。 本文将会介绍几种获取 Spring Boot 应用 PID 的方法。 ApplicationPidFileWriter ApplicationPidFileWriter 是 Spring Boot 提供的一个 Listener,它可以在应用启动后把 PID 写入到指定的文件。 它需要在启动前,通过编程式配置到应用中,并且需要在配置文件中指定要写入 PID 的文件。 application.yaml 配置如下: spring: pid: # 写入 PID 的文件,可以是相对路径或绝对路径 file: app.pid # 如果 PID 无法写入,是否抛出异常 fail-on-write-error: true 在启动前,配置 ApplicationPidFileWriter 监听器: import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.context.ApplicationPidFileWriter; @SpringBootApplication public class DemoApplication { public static void main(String[] args) { SpringApplication springApplication = new SpringApplicationBuilder() .listeners(new ApplicationPidFileWriter()) // PID 监听 .