教程

在 Servlet Filter 中自动装配 Spring Bean

1、简介 Servlet Filter(过滤器)为拦截和处理传入的请求提供了强大的机制。 本文将会带你了解在 Servlet Filter 中无缝获取 Spring Bean 的各种方法,这种需求在 Spring Web 应用中很常见。 2、Servlet Filter 中 @Autowired 的限制 Spring 的依赖注入机制 @Autowired,是一种方便的方式来将依赖注入到由 Spring 管理的组件中。但它无法与 Servlet Filter 完美配合。这是因为 Servlet Filter 是由 Servlet 容器初始化的,通常是在 Spring 的 ApplicationContext 完全加载和初始化之前 。 因此,当容器实例化 Servlet Filter 时 ,Spring Context 可能尚未可用,从而导致在尝试使用 @Autowired 注解时 ,依赖为 null 或未初始化。 3、项目设置 创建一个通用的 LoggingService,它将自动装配到 Filter 中: @Service public class LoggingService { private final Logger logger = LoggerFactory.getLogger(this.getClass()); public void log(String message,String url){ logger.info("Logging Request {} for URI : {}",message,url); } } 然后,创建 Filter,拦截传入的 HTTP 请求,并使用 LoggingService 依赖记录 HTTP 方法和 URI 的详细信息:

Spring Data JPA 中的 Refresh 和 Fetch

1、简介 Java Persistence API(JPA)是连接 Java 对象和关系数据库的桥梁,允许我们无缝地持久化和检索数据。本文将会带你了解各种策略和技术,以便在 JPA 中进行保存操作后有效地刷新(Refresh)和获取(Fetch)实体。 2、了解 Spring Data JPA 中的实体管理 在 Spring Data JPA 中 ,实体管理围绕 JpaRepository 接口展开,该接口是与数据库交互的主要机制。通过继承了 CrudRepository 的 JpaRepository 接口 ,Spring Data JPA 为实体的持久化、检索、更新和删除提供了一套强大的方法。 此外, Spring 容器会将实体管理器(EntityManager) 自动注入这些 repository 接口。该组件是嵌入 Spring Data JPA 的 JPA 基础架构的一个组成部分,可促进与底层持久化上下文(Persistence Context)的交互和 JPA 查询的执行。 2.1、Persistence Context JPA 中的一个关键组件是持久化上下文(Persistence Context)。把这个上下文想象成一个临时存放区,JPA 在这里管理检索或创建实体的状态。 它可以确保: 实体是唯一的: 在任何时候,上下文中都只存在一个具有特定主键的实体实例。 跟踪更改: 实体管理器(EntityManager)会跟踪上下文中对实体属性所做的任何修改。 保持数据一致性: 在事务处理期间,实体管理器会将上下文中的更改与底层数据库同步。 2.2、JPA 实体的生命周期 JPA 实体有四个不同的生命周期阶段: 瞬时(New)、托管(Managed)、删除(Removed)和游离(Detached)。 当我们使用实体的构造函数创建一个新实体实例时,它处于 “瞬时” 状态。我们可以通过检查实体的 ID(主键)是否为 null 来验证这一点: Order order = new Order(); if (order.

写给 Java / Spring Boot 开发者的 Golang 教程

我使用 Java 很多年了,我非常喜欢 Java 及其生态系统。在 Java 生态系统中,Spring Boot 是我构建 Java 应用的首选框架。 前不久,我在一个项目中使用了 Golang,起初我对它的感觉褒贬不一。但用得越多,就越喜欢它。 每当我尝试学习一种新的语言或框架时,我都会尝试将新框架/语言的概念映射到我已经熟悉的框架/语言中。这有助于我更快地理解新框架/语言的生态系统。 学习任何新知识的最好方法就是用它来构建一些东西。因此,在本文中,我将带你了解如何使用 Go 构建一个 REST API,包括配置管理、日志记录、数据库访问等各个方面。 本文并不会涉及到 Golang 的基础知识,如如何声明变量、循环、函数等。 使用的库 Go 没有类似 Spring Boot 的框架。通常,Go 开发人员喜欢使用标准库,只添加必要的库来构建应用。 本文将会使用到以下库来在 Go 中构建一个 REST API: Gin Web Framework - Web 框架 Viper - 配置库 zap - 日志库 pgx - Go 的 PostgreSQL 驱动程序和工具包 golang-migrate - 数据迁移 安装 Go 和工具 你可以从 https://go.dev/doc/install 下载并安装 Go。安装完成后,将 Go bin 目录添加到 PATH 环境变量中。 export GOPATH=$HOME/go export PATH="$PATH:$GOPATH/bin" 你可以使用 VS Code、IntelliJ IDEA Ultimate(使用 Go 插件)、GoLand 或任何其他 IDE 进行 Go 开发。

Spring Data 3 中的新 CRUD Repository 接口

1、概览 本文将带你了解 Spring Data 3 中引入的新 Repository 接口。 Spring Data 3 引入了基于 List 的 CRUD Repository 接口,可用于替换返回 Iterable 的现有 CRUD Repository 接口。此外,分页和排序接口默认不继承原始 CRUD Repository,而是由用户自己选择。接下来看看这些接口与现有接口有何不同,以及如何使用它们。 2、项目设置 首先创建一个 Spring Boot 应用,其中包含一个简单的实体和将使用新接口的 Repository。 2.1、依赖 首先,为项目添加所需的 spring-boot-starter-data-jpa 依赖: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> <version>3.2.3</version> </dependency> 除此之外,还要配置数据库。可以使用任何 SQL 数据库,本文将使用 H2 内存数据库: <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> </dependency> 2.2、Entity 创建一个 Book 实体: @Entity public class Book { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String title; private String author; private String isbn; // 构造器、Getter、Setter } 有了实体后,来看看如何使用新接口与数据库交互。

使用 Keycloak 为 Spring Cloud Gateway 和 Spring Boot 微服务启用 OAuth2

本文将带你了解如何使用 Keycloak 为 Spring Cloud Gateway 和 Spring Boot 微服务启用 OAuth2。本文是 上一篇文章 的扩展,并分析了 Spring Security 项目中提供的一些最新功能。 我们的架构由两个 Spring Boot 微服务组成、一个基于 Spring Cloud Gateway 的 API 网关和一个 Keycloak 授权服务器。Spring Cloud Gateway 在此充当 OAuth2 客户端和 OAuth2 资源服务器。对于任何传入请求,它都会在将流量转发到下游服务之前验证 Access Token。对于任何未经验证的请求,它都会使用 Keycloak 初始化一个授权码授权的流程。我们的方案需要包括内部微服务之间的通信。它们都隐藏在 API 网关后面。caller 应用调用 callme 应用暴露的端点。通信中使用的 HTTP 客户端必须使用网关发送的 Access Token。 源码 本文中的代码托管在 Github,你可以克隆这个 Repository,进入到 oauth 目录,其中包含了两个 Spring Boot 微服务:callme 和 caller。当然,还有构建在 Spring Cloud Gateway 之上的 gateway 应用。之后,只需按照说明操作即可。 运行并配置 Keycloak 我们以 Docker 容器的形式运行 Keycloak。默认情况下,Keycloak 在 8080 端口上公开 API 和 Web 控制台。还需要通过环境变量设置管理员用户名和密码。下面是运行 Keycloak 容器的命令:

启用 Spring Cloud Gateway 的 OAuth2 支持,并将其与 Keycloak 集成

Spring Cloud Gateway 的 OAuth2 支持是微服务安全流程的关键部分。当然,使用 API 网关模式的主要原因是将服务隐藏起来,不对外部客户端可见。然而,在隐藏服务时,并没有对其进行安全保护。本文将带你了解如何使用 Spring Security 和 Keycloak 设置 Spring Cloud Gateway 的 OAuth2 功能。 源码 本文中的源码托管在 Github 上,你可以克隆 sample-spring-security-microservices 仓库,然后按照说明进行安装和部署即可。 在 Spring Cloud Gateway 中启用 OAuth2 要为 Spring Cloud Gateway 应用启用 OAuth2 支持,除了启用网关功能所必需的 spring-cloud-starter-gateway 依赖外,还需要添加 spring-boot-starter-oauth2-client 以启用 Spring Security 对 OAuth 2.0 授权框架和 OpenID Connect Core 1.0 的客户端支持,以及 spring-cloud-starter-security 来激活 TokenRelay Filter。 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-oauth2-client</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-security</artifactId> </dependency> 接下来为 OAuth2 客户端提供配置设置。因为要与 Keycloak 集成,所以应将 registrationId 的名称(spring.

在 Java 中使用 Blowfish 加密算法

1、概览 Blowfish 加密算法最初是作为 DES 加密算法的替代方案而设计的,是当今最流行的加密算法之一。Blowfish 是一种对称的分组加密算法,由 Bruce Schneier 于 1993 年设计 。该算法的块大小为 64 位,密钥长度为 446 位,优于 DES 和 3DES 算法。 本文将带你了解如何使用 Java Cryptography Architecture(JCA)中提供的 Blowfish 算法实现加密和解密。 2、生成密钥 由于 Blowfish 是一种对称加密算法,它在加密和解密过程中使用相同的密钥。所以,接下来我们要创建一个密钥来加密文本。这个密钥应该被安全地保存,不应该在公共场合分享。 定义密钥: // 定义密钥 String secretKey = "MyKey123"; byte[] keyData = secretKey.getBytes(); //使用 Blowfish 算法创建 SecretKeySpec SecretKeySpec secretKeySpec = new SecretKeySpec(keyData, "Blowfish"); 接下来,就可以通过加密模式构建 Cipher 了: // 使用 Blowfish 算法创建 Cipher Cipher cipher = Cipher.getInstance("Blowfish"); 然后,使用加密模式(Cipher.ENCRYPT_MODE)初始化 cipher,并指定 Secret Key: // 使用 Secret Key 在加密模式下初始化 cipher cipher.

从 Spring Security 5 迁移到 Spring Security 6/Spring Boot 3

1、概览 Spring Security 6 有几处重大变化,包括删除了一些类和已废弃的方法,并引入了一些新方法。 从 Spring Security 5 迁移到 Spring Security 6 可以在不破坏现有代码的情况下逐步完成。此外,还可以使用 OpenRewrite 等第三方插件来促进向最新版本的迁移。 本文将带你了解如何把 Spring Security 5 的现有应用迁移到 Spring Security 6(替换过时的方法,并利用 Lambda DSL 简化配置。此外,还利用 OpenRewrite 加快迁移速度)。 2、Spring Security 和 Spring Boot 版本 Spring Boot 基于 Spring 框架,各版本的 Spring Boot 使用最新版本的 Spring 框架。Spring Boot 2 默认使用 Spring Security 5,而 Spring Boot 3 使用 Spring Security 6。 要在 Spring Boot 应用中使用 Spring Security,首先需要在 pom.xml 中添加 spring-boot-starter-security 依赖。 可以在 pom.xml 的 properties 部分 指定所需的版本,从而覆盖默认的 Spring Security 版本 :

在 Spring Boot 中处理 Kafka Offset(偏移量)

本文将带你了解如何使用 Spring Boot 和 Spring Kafka 管理 Kafka 消费者偏移量(Offset)。 在之的一篇文章中,主要说明了应用处理 Kafka 消息的方式可能会影响系统的整体性能,并没有考虑消费者端的消息重复或消息丢失等问题。本文将会介绍这些话题。 1、源码 本文中的源码托管在 GitHub,你可以克隆它到本地,然后按照说明中的步骤操作即可。 2、简介 在开始之前,首先要说明一些与使用 Spring Kafka 提交偏移量有关的重要事项。首先,默认情况下,Spring Kafka 会将消费者的 enable.auto.commit 属性设置为 false。这意味着提交偏移量的责任在于框架,而非 Kafka。当然,我们可以通过将该属性设置为 true 来改变默认行为。顺便说一句,这也是 Spring Kafka 2.3 之前的默认做法。 禁用了 Kafka 自动提交(Auto Commit)后,我们就可以利用 Spring Kafka 提供的 7 种不同的提交策略。本文不会分析所有策略,只分析最重要的几种。默认策略是 BATCH。为了设置不同的策略,需要覆盖 AckMode,例如在 Spring Boot application.properties 中设置 spring.kafka.listener.ack-mode 属性的值。 首先来看看 BATCH 模式。 3、Spring Boot Kafka 应用示例 为了测试使用 Spring Kafka 进行的偏移提交,我们将创建两个简单的应用:producer (生产者)和 consumer(消费者)。生产者向 Topic 发送规定数量的消息,而消费者接收并处理这些消息。下面是生产者 @RestController 的实现。它允许我们按需向 transactions Topic 发送指定数量的消息: @RestController public class TransactionsController { private static final Logger LOG = LoggerFactory .

使用最新的Mistral AI API,在 Java 和 Spring AI 中进行函数调用

领先的开源大型语言模型开发商 Mistral AI 宣布,其尖端模型新增了 函数调用 支持。 函数调用 是一种便于 LLM 与外部工具和 API 集成的功能。它使语言模型能够请求执行客户端函数,从而访问必要的运行时信息或动态执行任务。 本文将带你了解如何将 Mistral AI 的新函数调用功能与 Java 特别是 Spring AI 结合使用。 如果你对底层的 Java 客户端的详细细节不感兴趣,不想浪费时间,可以直接看 使用 Spring AI 调用函数 章节。 1、使用 Java 调用函数 如果你想使用 Java 和 Spring AI 测试最新的 Mistral AI 功能,你会发现 Mistral 不支持 Java 客户端,也还没有发布函数调用 API。 因此,我不得不通过探索他们的 JavaScript/Python 客户端来解决这个问题。下面是一个类图,说明了 API 的各个组件及其相互联系。 熟悉 OpenAI API 的人会注意到,Mistral AI 的新 API 几乎与 OpenAI API 相同,只有一些细微差别。不过,还有一个重要的限制: 在撰写本文时,Mistral AI 不支持并行函数调用,这使它与 OpenAI、Azure OpenAI 和 Vertex AI Gemini 提供的最新 LLM 模型有所不同。