Appearance
CAS 7.3 + Spring Boot 3.x + Java 21 新特性实战:拥抱现代 Java 生态的全面升级
作者: 必码 | bima.cc
前言:为什么需要这次升级
在企业级单点登录(SSO)领域,Apereo CAS 一直是最成熟、功能最丰富的开源解决方案之一。然而,技术生态的快速演进使得旧版本 CAS 面临着诸多挑战:
- 安全合规压力:CAS 5.3 基于 Spring Boot 1.x 和 Java 8,已无法获得安全补丁支持
- 生态兼容性:Spring Boot 2.x 已于 2023 年底结束商业支持,大量第三方库停止维护旧版 API
- 性能瓶颈:传统线程模型在高并发场景下的资源开销问题日益突出
- 云原生需求:容器化、Kubernetes 编排、Service Mesh 等现代运维体系要求应用具备更好的适配能力
CAS 7.3.4 的发布,标志着 Apereo CAS 正式全面拥抱现代 Java 生态。它基于 Java 21(LTS)、Spring Boot 3.5.6、Spring Framework 6.x 和 Jakarta EE 10 构建,是一次从底层运行时到上层应用架构的全面升级。
本文将基于我们团队实际完成的 CAS Overlay 项目迁移(从 CAS 5.3/6.6 升级至 7.3.4),逐一解析每个技术维度的变化,并提供可直接参考的配置示例和代码片段。
一、CAS 7.3 技术栈全景
1.1 核心版本矩阵
CAS 7.3 不是一个简单的功能迭代,而是一次底层技术栈的全面换代。以下是核心依赖版本对照:
| 技术组件 | CAS 5.3 | CAS 6.6 | CAS 7.3 | 变化说明 |
|---|---|---|---|---|
| Java | 8 / 11 | 11 / 17 | 21 (LTS) | 最低要求 Java 21 |
| Spring Boot | 1.5.x | 2.7.x | 3.5.6 | 大版本跨越 |
| Spring Framework | 4.3.x | 5.3.x | 6.x | 核心框架重构 |
| Gradle | 4.10.3 | 7.6.4 | 9.1.0 | 构建工具全面升级 |
| Jakarta EE | Java EE 7 | Java EE 8 | Jakarta EE 10 | 命名空间全面迁移 |
| Servlet | 3.1 | 4.0 | 6.0 | API 规范升级 |
| MyBatis-Spring | 1.3.1 | 1.3.1 | 3.0.3 | 跨越式版本升级 |
| 连接池 | commons-dbcp 1.4 | commons-dbcp 1.4 | commons-dbcp2 2.10.0 | 全新连接池实现 |
| Bootstrap | 3.x | 4.x | 5.3.3 | 前端框架大版本升级 |
| jQuery | 2.x | 3.x | 3.7.1 | 稳定版本 |
| Docker 基础镜像 | openjdk:8-jre | adoptopenjdk:11-jre | azul/zulu-openjdk:21 | 更现代的 JDK 发行版 |
1.2 Gradle 构建配置概览
CAS 7.3 的 gradle.properties 文件清晰地定义了整个技术栈的版本基线:
properties
# CAS 7.3.4 核心版本定义
cas.version=7.3.4
springBootVersion=3.5.6
# Java 版本要求(源码和目标字节码均为 21)
sourceCompatibility=21
targetCompatibility=21
# JVM 供应商选择(支持多种发行版)
jvmVendor=AMAZON
# 构建工具版本
lombokVersion=1.18.42
jibVersion=3.5.3
gradleCyclonePluginVersion=3.2.0
gradleDockerPluginVersion=9.4.0
gradleFreeFairPluginVersion=9.2.0
# 容器镜像配置
baseDockerImage=azul/zulu-openjdk:21
containerImageOrg=apereo
containerImageName=cas1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
1.3 依赖管理机制变化
CAS 7.3 采用了更加严格的依赖管理策略。在 build.gradle 中,依赖管理通过两个核心 BOM(Bill of Materials)实现:
groovy
dependencies {
// CAS BOM:统一管理所有 CAS 模块版本
implementation enforcedPlatform("org.apereo.cas:cas-server-support-bom:${project.'cas.version'}")
// Spring Boot BOM:统一管理 Spring 生态版本
implementation platform(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES)
}1
2
3
4
5
6
7
2
3
4
5
6
7
关键变化点:
enforcedPlatform替代了旧版的platform,强制使用 BOM 中指定的版本,不允许任何版本覆盖- 所有 CAS 模块依赖无需显式指定版本号,由 BOM 统一管控
- 移除了
io.spring.gradle:dependency-management-plugin,改用 Gradle 原生的 platform 机制
1.4 Java Toolchain 机制
CAS 7.3 引入了 Gradle Java Toolchain,实现构建 JDK 与运行 JDK 的分离:
groovy
java {
toolchain {
languageVersion = JavaLanguageVersion.of(project.targetCompatibility)
// 支持多种 JVM 供应商
def chosenJvmVendor = null
if (project.jvmVendor != null) {
try {
// Gradle 8.x 枚举写法
chosenJvmVendor = JvmVendorSpec."${project.jvmVendor?.toUpperCase()}"
} catch (MissingPropertyException e) {
// Gradle 7.x 兼容回退
chosenJvmVendor = JvmVendorSpec.of(project.jvmVendor?.toUpperCase())
}
}
if (chosenJvmVendor != null) {
vendor = chosenJvmVendor
}
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
这意味着你可以在 JDK 17 上运行 Gradle,但编译目标仍然是 JDK 21。Gradle 会自动检测并下载所需的 JDK 版本(通过 Foojay 插件)。
二、Java 21 新特性在 CAS 中的应用
Java 21 于 2023 年 9 月正式发布,是继 Java 17 之后的最新 LTS 版本。它带来了多项革命性特性,这些特性在 CAS 7.3 的内部实现和我们的 Overlay 项目中都有广泛应用。
2.1 Record 类:不可变数据载体
JEP 395/JSR 390 - 正式特性
Record 类是 Java 引入的用于定义不可变数据载体的声明式语法。在 CAS 7.3 中,Record 被大量用于定义配置模型、认证凭证和服务注册信息等数据传输对象。
传统方式 vs Record 方式
java
// ===== 传统方式(CAS 5.x/6.x 时代)=====
public class CasServiceDefinition {
private final String serviceId;
private final String name;
private final long id;
private final int evaluationOrder;
private final boolean enabled;
public CasServiceDefinition(String serviceId, String name,
long id, int evaluationOrder, boolean enabled) {
this.serviceId = serviceId;
this.name = name;
this.id = id;
this.evaluationOrder = evaluationOrder;
this.enabled = enabled;
}
// 需要手动编写 getter、equals、hashCode、toString...
public String getServiceId() { return serviceId; }
public String getName() { return name; }
public long getId() { return id; }
public int getEvaluationOrder() { return evaluationOrder; }
public boolean isEnabled() { return enabled; }
@Override
public boolean equals(Object o) { /* ... */ }
@Override
public int hashCode() { /* ... */ }
@Override
public String toString() { /* ... */ }
}
// ===== Record 方式(CAS 7.3 时代)=====
public record CasServiceDefinition(
String serviceId,
String name,
long id,
int evaluationOrder,
boolean enabled
) {}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
Record 的核心优势:
- 零样板代码:编译器自动生成构造器、访问器、
equals()、hashCode()和toString() - 不可变性保证:所有字段隐式为
final,线程安全 - 语义清晰:类声明即文档,一眼就能看出这是一个纯数据载体
- 与 Pattern Matching 深度集成:可以在
switch和instanceof中直接解构
在 CAS Overlay 中的实际应用
在我们的自定义认证模块中,使用 Record 定义认证请求和响应:
java
/**
* 认证请求 - 使用 Record 定义不可变数据载体
*/
public record AuthenticationRequest(
String username,
String credential,
String clientIp,
String serviceUrl,
Instant timestamp
) {
// 紧凑构造器用于参数校验
public AuthenticationRequest {
Objects.requireNonNull(username, "用户名不能为空");
Objects.requireNonNull(credential, "凭证不能为空");
if (username.isBlank()) {
throw new IllegalArgumentException("用户名不能为空白");
}
}
// 可以添加自定义方法
public boolean isFromInternalNetwork() {
return clientIp != null && clientIp.startsWith("10.");
}
}
/**
* 认证结果 - 密封接口配合 Record 使用
*/
public sealed interface AuthResult
permits AuthResult.Success, AuthResult.Failure, AuthResult.RequiresMfa {
record Success(String principal, Map<String, Object> attributes,
Instant authenticatedAt) implements AuthResult {}
record Failure(String errorCode, String errorMessage,
int remainingAttempts) implements AuthResult {}
record RequiresMfa(String principal, List<String> availableFactors)
implements AuthResult {}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
2.2 Pattern Matching for switch
JEP 441 - 正式特性
Java 21 将 Pattern Matching for switch 提升为正式特性,允许在 switch 中直接进行类型模式匹配,极大地简化了条件分支代码。
传统 switch vs 模式匹配 switch
java
// ===== 传统方式 =====
public String processAuthenticationResult(Object result) {
if (result instanceof AuthResult.Success) {
AuthResult.Success success = (AuthResult.Success) result;
return "认证成功: " + success.principal();
} else if (result instanceof AuthResult.Failure) {
AuthResult.Failure failure = (AuthResult.Failure) result;
return "认证失败: " + failure.errorMessage();
} else if (result instanceof AuthResult.RequiresMfa) {
AuthResult.RequiresMfa mfa = (AuthResult.RequiresMfa) result;
return "需要多因素认证: " + mfa.availableFactors();
}
return "未知结果";
}
// ===== Pattern Matching for switch(Java 21)=====
public String processAuthenticationResult(Object result) {
return switch (result) {
case AuthResult.Success(var principal, var attrs, var time)
-> "认证成功: " + principal + " 于 " + time;
case AuthResult.Failure(var code, var msg, var remaining)
-> "认证失败[%s]: %s (剩余尝试次数: %d)".formatted(code, msg, remaining);
case AuthResult.RequiresMfa(var principal, var factors)
-> "需要多因素认证: " + String.join(", ", factors);
case null -> "结果为空";
default -> "未知结果类型: " + result.getClass().getSimpleName();
};
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
Record 解构模式
当 Record 与 Pattern Matching 结合时,可以直接在 case 标签中解构 Record 的组件:
java
public void handleCasEvent(Object event) {
switch (event) {
// 直接解构 Record 组件
case TicketGrantingTicketCreated(
var ticketId, var principal, var service
) -> {
log.info("TGT 创建: ticket={}, principal={}, service={}",
ticketId, principal, service);
}
case ServiceTicketValidated(
var ticketId, var principal, var attributes
) when attributes.containsKey("memberOf") -> {
// 带守卫条件的模式匹配
var groups = (List<String>) attributes.get("memberOf");
log.info("管理员验证通过: {}, 组: {}", principal, groups);
}
case AuthenticationSuccess(
var principal, _, var timestamp // 使用 _ 忽略不需要的组件
) -> {
log.info("认证成功: {} at {}", principal, timestamp);
}
default -> log.debug("未处理的事件: {}", event);
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
守卫条件(Guard) 是 Java 21 中新增的语法,允许在模式匹配后追加 when 子句进行额外条件过滤。这在 CAS 的事件处理和认证策略路由中极为有用。
2.3 Sealed Classes(密封类)
JEP 409/JSR 417 - 正式特性
密封类允许开发者精确控制哪些类可以继承或实现一个给定的类型。在 CAS 7.3 中,密封类被用于构建类型安全的认证处理器层次结构。
密封类在认证体系中的应用
java
/**
* 密封接口:认证处理器基类
* 仅允许指定的三个子类实现
*/
public sealed interface AuthenticationHandler
permits UsernamePasswordHandler,
X509CertificateHandler,
OAuth2TokenHandler {
AuthenticationResult authenticate(AuthenticationRequest request)
throws AuthenticationException;
boolean supports(CredentialType type);
}
// ===== 允许的子类实现 =====
/**
* 用户名密码认证处理器 - final 不可再被继承
*/
public final class UsernamePasswordHandler implements AuthenticationHandler {
@Override
public AuthenticationResult authenticate(AuthenticationRequest request) {
// 实现用户名密码认证逻辑
return new AuthenticationResult.Success(request.username());
}
@Override
public boolean supports(CredentialType type) {
return type == CredentialType.USERNAME_PASSWORD;
}
}
/**
* X.509 证书认证处理器
*/
public final class X509CertificateHandler implements AuthenticationHandler {
@Override
public AuthenticationResult authenticate(AuthenticationRequest request) {
// 实现 X.509 证书认证逻辑
return new AuthenticationResult.Success(request.username());
}
@Override
public boolean supports(CredentialType type) {
return type == CredentialType.X509_CERTIFICATE;
}
}
/**
* OAuth2 Token 认证处理器
*/
public final class OAuth2TokenHandler implements AuthenticationHandler {
@Override
public AuthenticationResult authenticate(AuthenticationRequest request) {
// 实现 OAuth2 Token 认证逻辑
return new AuthenticationResult.Success(request.username());
}
@Override
public boolean supports(CredentialType type) {
return type == CredentialType.OAUTH2_TOKEN;
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
密封类的三层权限控制:
| 修饰符 | 含义 | 适用场景 |
|---|---|---|
sealed | 仅允许列出的类继承 | 基类/接口 |
non-sealed | 重新开放继承 | 中间层 |
final | 完全封闭,不可继承 | 叶子节点 |
密封类与 Pattern Matching 的协同
密封类最大的价值在于与 Pattern Matching 的协同——编译器能够检查 switch 表达式是否穷尽了所有可能的子类型:
java
public String getHandlerDescription(AuthenticationHandler handler) {
// 编译器会检查是否覆盖了所有 AuthenticationHandler 的子类型
// 如果遗漏某个子类,会发出警告
return switch (handler) {
case UsernamePasswordHandler h -> "用户名密码认证";
case X509CertificateHandler h -> "X.509 证书认证";
case OAuth2TokenHandler h -> "OAuth2 Token 认证";
// 不需要 default 分支,编译器知道所有可能的子类型
};
}1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
2.4 Virtual Threads(虚拟线程)
JEP 444 - 正式特性
虚拟线程是 Java 21 中最具革命性的特性。它引入了一种轻量级线程实现,由 JVM 而非操作系统管理,可以轻松创建数百万个线程而不会耗尽系统资源。
传统线程 vs 虚拟线程
java
// ===== 传统平台线程(每个线程占用约 1MB 栈空间)=====
ExecutorService executor = Executors.newFixedThreadPool(200);
// 200 个并发已经是传统线程池的上限
// ===== 虚拟线程(每个线程仅占用约 1KB 内存)=====
ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor();
// 可以轻松处理百万级并发任务1
2
3
4
5
6
7
2
3
4
5
6
7
在 CAS 中的潜在应用场景
CAS 作为 SSO 服务器,在高并发登录场景下(如开学季集中认证),虚拟线程可以显著提升吞吐量:
java
/**
* 使用虚拟线程处理并发认证请求
*/
@Configuration
public class VirtualThreadConfig {
@Bean
public AsyncTaskExecutor asyncTaskExecutor() {
// Spring Boot 3.2+ 原生支持虚拟线程
var executor = new SimpleAsyncTaskExecutor("cas-virtual-");
executor.setVirtualThreads(true);
return executor;
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
在 application.yml 中启用虚拟线程:
yaml
spring:
threads:
virtual:
enabled: true1
2
3
4
2
3
4
虚拟线程的性能优势:
| 指标 | 平台线程 | 虚拟线程 |
|---|---|---|
| 线程创建成本 | ~1ms | ~1μs(快 1000 倍) |
| 内存占用 | ~1MB/线程 | ~1KB/线程 |
| 最大线程数 | ~数千 | ~数百万 |
| 上下文切换 | 操作系统内核态 | JVM 用户态 |
| 适用场景 | CPU 密集型 | I/O 密集型 |
注意: 虚拟线程最适合 I/O 密集型操作(如数据库查询、HTTP 调用、LDAP 查询等),这正是 CAS 认证流程的典型特征。对于 CPU 密集型操作(如加密解密),仍应使用平台线程。
2.5 String Templates(字符串模板)
JEP 430 - 预览特性
字符串模板是 Java 21 中的预览特性,提供了一种更安全、更灵活的字符串插值机制。虽然目前仍是预览状态,但 CAS 7.3 的代码库中已经可以看到相关的设计思路。
java
// ===== 传统字符串拼接 =====
String message = "用户 " + username + " 于 " + Instant.now() + " 从 " + clientIp + " 登录成功";
// ===== String.format(类型不安全)=====
String message = String.format("用户 %s 于 %s 从 %s 登录成功", username, Instant.now(), clientIp);
// ===== String Templates(Java 21 预览特性,需启用 --enable-preview)=====
String message = STR."用户 \{username} 于 \{Instant.now()} 从 \{clientIp} 登录成功";
// ===== 模板处理器可以自定义验证逻辑 =====
// 例如:SQL 参数化查询模板
String query = SQL."SELECT * FROM users WHERE username = \{username} AND status = \{status}";
// SQL 模板处理器会自动进行参数绑定,防止 SQL 注入1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
String Templates 的四种内置模板处理器:
| 处理器 | 功能 | 示例 |
|---|---|---|
STR | 基本字符串插值 | STR."Hello \{name}" |
FMT | 格式化插值 | FMT."Value: %.2f\{price}" |
RAW | 原始片段访问 | RAW."...\{expr}..." |
JSON | JSON 字符串构建 | JSON."{\"name\": \"\{name}\"}" |
2.6 Generational ZGC(分代 ZGC)
JEP 439 - 正式特性
Generational ZGC 是 ZGC 垃圾收集器的分代增强版本。它将堆内存分为年轻代和老年代,针对 CAS 这类"大部分对象朝生夕灭"的应用场景进行了深度优化。
启用 Generational ZGC
bash
# 启用分代 ZGC(Java 21 默认启用)
java -XX:+UseZGC -XX:+ZGenerational -jar cas.jar
# 推荐的 JVM 参数配置
java \
-XX:+UseZGC \
-XX:+ZGenerational \
-Xms2g \
-Xmx4g \
-XX:+AlwaysPreTouch \
-XX:MaxGCPauseMillis=10 \
-jar cas.jar1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
ZGC 分代 vs 非分代的性能对比
| 指标 | ZGC(非分代) | Generational ZGC | G1GC |
|---|---|---|---|
| 最大暂停时间 | < 1ms | < 1ms | ~200ms |
| 吞吐量 | ~95% | ~98% | ~92% |
| 内存开销 | 较高 | 中等 | 较低 |
| 适用堆大小 | 8MB-16TB | 8MB-16TB | < 32GB |
| 分代支持 | 无 | 有 | 有 |
在 CAS 场景中的实际效果:
CAS 的典型工作负载特征是大量短生命周期的 Ticket 对象(TGT、ST、PGT 等)。Generational ZGC 的年轻代回收可以高效清理这些临时对象,将 GC 停顿时间降低 90% 以上,同时提升整体吞吐量。
2.7 Foreign Function & Memory API(FFM API)
JEP 442 - 预览特性
FFM API 提供了一种安全、高效的方式与原生代码(C/C++ 库)和原生内存交互,替代了传统的 JNI 机制。
java
// ===== 传统 JNI 方式(需要编写 C 代码、生成头文件、编译动态链接库)=====
// 步骤:1. 编写 Java native 方法声明
// 2. javah 生成 C 头文件
// 3. 编写 C 实现代码
// 4. 编译为动态链接库
// 5. System.loadLibrary() 加载
// ===== FFM API 方式(纯 Java 实现)=====
import java.lang.foreign.*;
import java.lang.invoke.*;
// 链接 C 标准库的 strlen 函数
Linker linker = Linker.nativeLinker();
SymbolLookup stdlib = linker.defaultLookup();
MethodHandle strlen = linker.downcallHandle(
stdlib.lookup("strlen").orElseThrow(),
FunctionDescriptor.of(ValueLayout.JAVA_LONG, ValueLayout.ADDRESS)
);
// 调用原生函数
try (Arena arena = Arena.ofConfined()) {
MemorySegment str = arena.allocateFrom("Hello CAS 7.3!");
long len = (long) strlen.invokeExact(str);
System.out.println("字符串长度: " + len);
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
在 CAS 中的潜在应用: FFM API 可以用于与 LDAP 的原生 C 库、Kerberos 库以及硬件安全模块(HSM)进行高性能交互,无需编写 JNI 桥接代码。
三、Spring Boot 3.x 迁移要点
从 Spring Boot 2.x 到 3.x 是一次跨越式升级,涉及命名空间变更、API 重构和自动配置机制的全面调整。
3.1 javax 到 jakarta 命名空间迁移
这是 Spring Boot 3.x 迁移中最基础、影响面最广的变化。Jakarta EE 将包名从 javax.* 迁移到 jakarta.*,这是一个不可逆的破坏性变更。
java
// ===== Spring Boot 2.x(javax 命名空间)=====
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.Filter;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.persistence.Entity;
import javax.persistence.Id;
// ===== Spring Boot 3.x(jakarta 命名空间)=====
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.Filter;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
批量迁移策略:
对于大型项目,建议使用 OpenRewrite 进行自动化迁移:
xml
<!-- pom.xml 中添加 OpenRewrite 插件 -->
<plugin>
<groupId>org.openrewrite.maven</groupId>
<artifactId>rewrite-maven-plugin</artifactId>
<version>5.20.0</version>
<configuration>
<activeRecipes>
<recipe>org.openrewrite.java.migrate.jakarta.JavaxMigrationToJakarta</recipe>
</activeRecipes>
</configuration>
</plugin>1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
对于 Gradle 项目:
groovy
// build.gradle 中添加 OpenRewrite 插件
plugins {
id 'org.openrewrite.rewrite' version '6.8.0'
}
rewrite {
activeRecipe('org.openrewrite.java.migrate.jakarta.JavaxMigrationToJakarta')
}1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
3.2 Spring Security 6.x 变化
Spring Security 6.x 带来了声明式安全配置的重大变化,从传统的继承 WebSecurityConfigurerAdapter 转向组件化的配置方式。
java
// ===== Spring Boot 2.x 方式(已废弃)=====
@Configuration
@EnableWebSecurity
public class CasSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/cas/status/**").permitAll()
.antMatchers("/cas/login").permitAll()
.anyRequest().authenticated()
.and()
.csrf().disable();
}
}
// ===== Spring Boot 3.x 方式(组件化配置)=====
@Configuration
@EnableWebSecurity
public class CasSecurityConfig {
@Bean
public SecurityFilterChain casSecurityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/cas/status/**").permitAll()
.requestMatchers("/cas/login").permitAll()
.anyRequest().authenticated()
)
.csrf(csrf -> csrf.disable())
.headers(headers -> headers
.contentSecurityPolicy(csp -> csp
.policyDirectives("default-src 'self'")
)
);
return http.build();
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
关键 API 变更对照:
| Spring Security 5.x | Spring Security 6.x | 说明 |
|---|---|---|
antMatchers() | requestMatchers() | 匹配器方法重命名 |
authorizeRequests() | authorizeHttpRequests() | 授权配置方法重命名 |
WebSecurityConfigurerAdapter | SecurityFilterChain Bean | 配置方式重构 |
access("hasRole('ADMIN')") | hasRole("ADMIN") | 简化表达式 |
and() | 链式调用 | 不再需要 and() 连接 |
3.3 Spring MVC vs WebFlux 选择
CAS 7.3 默认使用 Spring MVC(基于 Servlet),但也支持 WebFlux(基于 Reactive)。在 CAS 的典型使用场景中,我们推荐继续使用 Spring MVC,原因如下:
| 维度 | Spring MVC | WebFlux |
|---|---|---|
| 编程模型 | 同步/阻塞 | 异步/非阻塞 |
| 学习曲线 | 低 | 高 |
| 生态兼容性 | 成熟 | 发展中 |
| CAS 支持度 | 完整支持 | 部分支持 |
| 适用场景 | 传统 Web 应用 | 高并发流式处理 |
yaml
# application.yml - 确保 CAS 使用 Servlet 栈
spring:
main:
web-application-type: servlet1
2
3
4
2
3
4
3.4 自动配置变更
Spring Boot 3.x 对自动配置机制进行了多项调整:
yaml
# ===== 旧版配置(Spring Boot 2.x)=====
spring:
http:
encoding:
charset: UTF-8
enabled: true
force: true
# ===== 新版配置(Spring Boot 3.x)=====
server:
servlet:
encoding:
charset: UTF-8
enabled: true
force: true1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
主要配置属性迁移对照:
| 旧属性路径 | 新属性路径 | 说明 |
|---|---|---|
spring.http.encoding.charset | server.servlet.encoding.charset | 字符编码 |
spring.http.encoding.enabled | server.servlet.encoding.enabled | 编码启用 |
spring.http.encoding.force | server.servlet.encoding.force | 强制编码 |
spring.mvc.locale | spring.web.locale | 区域设置 |
spring.mvc.locale-resolver | spring.web.locale-resolver | 区域解析器 |
management.endpoints.web.base-path | management.endpoints.web.base-path | 端点路径(不变) |
management.endpoints.web.exposure.include | management.endpoints.web.exposure.include | 端点暴露(不变) |
3.5 management.endpoints 新配置方式
CAS 7.3 对 Actuator 端点配置进行了优化:
yaml
# CAS 7.3 推荐的 Actuator 配置
management:
endpoints:
web:
exposure:
include: health,info
exclude: refresh,shutdown
base-path: /status
endpoint:
health:
enabled: true
show-details: when_authorized
info:
enabled: true
security:
enabled: true
roles: ACTUATOR,ADMIN
health:
status:
order: WARN, DOWN, OUT_OF_SERVICE, UNKNOWN, UP1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Spring Boot 3.5.x 新增的 Actuator 特性:
- 严格的
.enabled属性:.enabled配置项现在只接受true或false,不再接受on/off/yes/no等变体 - 健康状态分组:支持自定义健康状态分组,便于不同角色查看不同粒度的健康信息
- 端点缓存:新增端点响应缓存配置,减少频繁查询的开销
四、Jakarta EE 10 迁移
Jakarta EE 10 是 Jakarta EE 迁移到 Eclipse 基金会后的第三个主要版本,带来了全面的 API 更新。
4.1 命名空间迁移全览
Jakarta EE 10 的核心变化是所有 Java EE/Jakarta EE 规范的包名从 javax.* 迁移到 jakarta.*。以下是 CAS 项目中涉及的主要迁移:
java
// ===== Servlet API =====
// 旧: import javax.servlet.http.HttpServletRequest;
// 新:
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
// ===== Validation API =====
// 旧: import javax.validation.Valid;
// 新:
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import jakarta.validation.ConstraintViolation;
// ===== Persistence API (JPA) =====
// 旧: import javax.persistence.Entity;
// 新:
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import jakarta.persistence.Column;
import jakarta.persistence.GeneratedValue;
// ===== Mail API =====
// 旧: import javax.mail.internet.MimeMessage;
// 新:
import jakarta.mail.internet.MimeMessage;
import jakarta.mail.internet.InternetAddress;
import jakarta.mail.Session;
// ===== XML Binding (JAXB) =====
// 旧: import javax.xml.bind.JAXBContext;
// 新:
import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.Marshaller;
import jakarta.xml.bind.Unmarshaller;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
4.2 影响范围分析
在我们的 CAS Overlay 项目中,Jakarta EE 10 迁移的影响范围如下:
| 影响领域 | 影响程度 | 迁移工作量 | 说明 |
|---|---|---|---|
| CAS 核心代码 | 无 | 无 | CAS 7.3 已完成内部迁移 |
| 自定义认证处理器 | 中 | 低 | 替换 import 语句即可 |
| 自定义 Web Filter | 中 | 低 | 替换 import 语句即可 |
| MyBatis 集成 | 低 | 极低 | MyBatis 不直接依赖 Jakarta |
| 数据库配置 | 低 | 极低 | commons-dbcp2 已使用 jakarta |
| 前端模板 | 无 | 无 | Thymeleaf 模板不受影响 |
| 第三方依赖 | 高 | 中 | 需检查所有依赖的兼容性 |
4.3 第三方依赖兼容性处理
在迁移过程中,我们发现部分第三方依赖尚未完成 Jakarta 迁移。CAS 7.3 的 build.gradle 中通过排除机制处理了这些冲突:
groovy
configurations {
all {
exclude(group: "cglib", module: "cglib")
exclude(group: "cglib", module: "cglib-full")
exclude(group: "org.slf4j", module: "slf4j-log4j12")
exclude(group: "org.slf4j", module: "slf4j-simple")
exclude(group: "ch.qos.logback", module: "logback-core")
exclude(group: "ch.qos.logback", module: "logback-classic")
}
}1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
特别注意: javax.mail:mail:1.4.7 是一个遗留依赖。在 CAS 7.3 中,应使用 org.eclipse.angus:angus-mail 或 com.sun.mail:jakarta.mail 替代:
groovy
// 推荐的 Jakarta Mail 依赖
implementation 'org.eclipse.angus:angus-mail:2.0.2'
// 或
implementation 'com.sun.mail:jakarta.mail:2.0.1'1
2
3
4
2
3
4
五、CAS 7.3 架构变化
CAS 7.3 在架构层面引入了多项重要变化,这些变化直接影响 Overlay 项目的配置和自定义方式。
5.1 CasInitializerConfig:全新初始化架构
CAS 7.3 引入了全新的 CasInitializerConfig 机制,替代了旧版的 CasWebApplicationInitializer。这是 CAS 初始化流程的根本性重构。
java
// ===== CAS 6.x 初始化方式 =====
public class CasWebApplicationInitializer
extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(
SpringApplicationBuilder builder) {
return builder
.sources(CasWebApplication.class)
.bannerMode(Banner.Mode.OFF);
}
}
// ===== CAS 7.3 初始化方式 =====
@Configuration
public class CasInitializerConfig {
@Bean
@ConditionalOnMissingBean
public CasWebApplicationInitializer casWebApplicationInitializer() {
return new CasWebApplicationInitializer();
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
关键变化:
- 模块化初始化:初始化逻辑从单一的
ServletInitializer拆分为多个可配置的@Bean - 条件装配:通过
@ConditionalOnMissingBean允许 Overlay 项目灵活覆盖默认行为 - 嵌入式容器支持:Tomcat、Jetty、Undertow 的初始化配置独立管理
5.2 @RefreshScope 配置热刷新
CAS 7.3 增强了对 @RefreshScope 的支持,允许在不重启应用的情况下动态更新配置:
java
@Configuration
public class DynamicCasConfiguration {
/**
* 可热刷新的服务注册配置
* 当配置中心推送更新时,该 Bean 会被重新创建
*/
@Bean
@RefreshScope
public ServiceRegistryConfig serviceRegistryConfig(
@Value("${cas.service-registry.json.location}") String location) {
return new ServiceRegistryConfig(location);
}
/**
* 可热刷新的认证策略配置
*/
@Bean
@RefreshScope
public AuthenticationPolicyConfig authenticationPolicyConfig() {
return new AuthenticationPolicyConfig(
maxAttempts = 5,
lockDuration = Duration.ofMinutes(30)
);
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
5.3 @ConditionalOnMissingBean 条件装配
CAS 7.3 大量使用 Spring Boot 的条件装配注解,使得 Overlay 项目的自定义配置更加优雅:
java
@Configuration
public class CasOverlayOverrideConfiguration {
/**
* 自定义数据源配置
* 仅当容器中不存在 DataSource Bean 时生效
*/
@Bean
@ConditionalOnMissingBean(DataSource.class)
public DataSource customDataSource() {
var ds = new BasicDataSource();
ds.setDriverClassName("com.mysql.cj.jdbc.Driver");
ds.setUrl("jdbc:mysql://localhost:3306/cas_db");
ds.setUsername("cas_user");
ds.setPassword("secure_password");
ds.setInitialSize(5);
ds.setMaxTotal(100);
ds.setMaxIdle(30);
ds.setMinIdle(5);
return ds;
}
/**
* 自定义认证事件发布器
*/
@Bean
@ConditionalOnMissingBean(AuthenticationEventPublisher.class)
public AuthenticationEventPublisher customEventPublisher(
ApplicationEventPublisher publisher) {
return new DefaultAuthenticationEventPublisher(publisher);
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
5.4 显式清除默认认证处理器
CAS 7.3 改变了认证处理器的注册机制。在旧版本中,CAS 会自动注册一组默认的认证处理器(如 AcceptUsersAuthenticationHandler)。在 7.3 中,需要显式控制这些默认行为:
yaml
# application.yml - 显式禁用默认的静态用户认证
cas:
authn:
accept:
enabled: false
users: ""1
2
3
4
5
6
2
3
4
5
6
java
/**
* 显式清除不需要的默认认证处理器
* 并注册自定义处理器
*/
@Configuration
public class CustomAuthenticationConfiguration {
@Bean
public AuthenticationHandler customDatabaseAuthenticationHandler(
DataSource dataSource) {
// 创建自定义的数据库认证处理器
var handler = new QueryDatabaseAuthenticationHandler();
handler.setDataSource(dataSource);
handler.setAuthenticationQuery(
"SELECT password FROM users WHERE username = ? AND status = 1");
handler.setPasswordEncoder(new BCryptPasswordEncoder());
return handler;
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
5.5 CasEmbeddedContainerUtils
CAS 7.3 新增了 CasEmbeddedContainerUtils 工具类,用于统一管理嵌入式容器的配置:
java
// CAS 7.3 内部使用 CasEmbeddedContainerUtils 管理容器配置
// 在 application.yml 中通过标准 Spring Boot 属性控制
server:
port: 8443
ssl:
enabled: true
key-store: classpath:keystore.jks
key-store-password: changeit
key-password: changeit
key-store-type: JKS
protocol: TLS
enabled-protocols: TLSv1.2,TLSv1.3
tomcat:
uri-encoding: UTF-8
remoteip:
enabled: true
protocol-header: X-Forwarded-Proto
port-header: X-Forwarded-Port
remote-ip-header: X-FORWARDED-FOR
connection-timeout: 20000
max-http-form-post-size: 2097152
min-spare-threads: 10
max-threads: 200
accesslog:
enabled: true
pattern: "%t %a \"%r\" %s (%D ms)"
suffix: .log
directory: /var/log/cas/tomcat1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
5.6 移除的模块和配置
CAS 7.3 移除了一些过时的模块和配置项,以下是我们在迁移中发现的主要移除:
| 移除项 | 替代方案 | 影响范围 |
|---|---|---|
cas-server-webapp-config | cas-server-webapp-init | 初始化模块 |
cas-server-support-oauth-services | cas-server-support-oauth-uma | OAuth 服务管理 |
pac4j-javaee | pac4j-jee | Pac4j 集成 |
| WAR 部署模式 | JAR 部署模式 | 打包方式 |
spring-boot-starter-logging | spring-boot-starter-log4j2 | 日志框架 |
六、MyBatis-Spring 3.x 升级
MyBatis-Spring 从 1.3.1 升级到 3.0.3,跨越了多个大版本,API 发生了显著变化。
6.1 版本变化概览
| 版本 | Spring 兼容性 | Java 兼容性 | 主要变化 |
|---|---|---|---|
| 1.3.1 | Spring 3.x - 5.x | Java 6+ | 基础集成 |
| 2.0.x | Spring 5.x | Java 8+ | 支持 Spring 5 |
| 2.1.x | Spring 5.x | Java 8+ | 增强注解支持 |
| 3.0.0 | Spring 6.x | Java 17+ | 全面支持 Spring Boot 3 |
| 3.0.3 | Spring 6.x | Java 17+ | Bug 修复 |
6.2 SqlSessionFactory 配置变化
xml
<!-- ===== MyBatis-Spring 1.3.1 配置方式 ===== -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<property name="mapperLocations" value="classpath:mapper/**/*.xml"/>
<property name="typeAliasesPackage" value="cc.bima.cas.model"/>
</bean>
<!-- ===== MyBatis-Spring 3.0.3 配置方式 ===== -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation" value="classpath:mybatis/mybatis-config.xml"/>
<property name="mapperLocations" value="classpath:mapper/**/*.xml"/>
<property name="typeAliasesPackage" value="cc.bima.cas.model"/>
<!-- 3.0.x 新增配置 -->
<property name="configurationProperties">
<props>
<prop key="cacheEnabled">true</prop>
<prop key="lazyLoadingEnabled">false</prop>
<prop key="multipleResultSetsEnabled">true</prop>
<prop key="useColumnLabel">true</prop>
<prop key="useGeneratedKeys">false</prop>
<prop key="defaultExecutorType">REUSE</prop>
</props>
</property>
</bean>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
6.3 MapperScan 注解变化
java
// ===== MyBatis-Spring 1.3.1 方式 =====
@Configuration
@MapperScan(basePackages = "cc.bima.cas.dao")
public class MyBatisConfig {
// ...
}
// ===== MyBatis-Spring 3.0.3 方式 =====
@Configuration
@MapperScan(
basePackages = "cc.bima.cas.dao",
sqlSessionFactoryRef = "sqlSessionFactory",
lazyInitialization = true // 3.0.x 新增:延迟初始化
)
public class MyBatisConfig {
@Bean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
var factory = new SqlSessionFactoryBean();
factory.setDataSource(dataSource);
factory.setConfigLocation(
new ClassPathResource("mybatis/mybatis-config.xml"));
factory.setMapperLocations(
new PathMatchingResourcePatternResolver()
.getResources("classpath:mapper/**/*.xml"));
return factory.getObject();
}
@Bean
public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
6.4 与 Spring Boot 3.x 的兼容性
MyBatis-Spring 3.0.3 完全兼容 Spring Boot 3.x 和 Jakarta EE 10。以下是推荐的集成配置:
groovy
// build.gradle - MyBatis 依赖配置
dependencies {
// MyBatis 核心
implementation "org.mybatis:mybatis:3.5.16"
implementation "org.mybatis:mybatis-spring:3.0.3"
// MyBatis Spring Boot Starter(如果使用)
// implementation "org.mybatis.spring.boot:mybatis-spring-boot-starter:3.0.3"
// 数据库驱动
implementation "mysql:mysql-connector-java:8.0.33"
// 连接池
implementation "org.apache.commons:commons-dbcp2:2.10.0"
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
MyBatis-Spring 3.0.3 的关键改进:
- Jakarta EE 10 兼容:全面支持
jakarta.*命名空间 - 延迟初始化:支持 Mapper Bean 的延迟初始化,加快启动速度
- 编译时注解处理:增强的注解处理器,提供更好的编译期检查
- Spring 6 事务集成:与 Spring 6 的事务管理深度集成
七、commons-dbcp 到 commons-dbcp2
从 Apache Commons DBCP 1.x 升级到 2.x,虽然包名从 commons-dbcp 变为 org.apache.commons:commons-dbcp2,但 API 也发生了重要变化。
7.1 API 变化
java
// ===== commons-dbcp 1.4(旧版)=====
import org.apache.commons.dbcp.BasicDataSource;
BasicDataSource ds = new BasicDataSource();
ds.setDriverClassName("com.mysql.jdbc.Driver"); // 旧驱动类名
ds.setMaxActive(100); // 最大连接数
ds.setMaxIdle(30); // 最大空闲连接
ds.setMinIdle(5); // 最小空闲连接
ds.setMaxWait(10000); // 最大等待时间(毫秒)
// ===== commons-dbcp2 2.10.0(新版)=====
import org.apache.commons.dbcp2.BasicDataSource;
BasicDataSource ds = new BasicDataSource();
ds.setDriverClassName("com.mysql.cj.jdbc.Driver"); // 新驱动类名
ds.setMaxTotal(100); // 原 maxActive -> maxTotal
ds.setMaxIdle(30); // 保持不变
ds.setMinIdle(5); // 保持不变
ds.setMaxWaitMillis(10000); // 原 maxWait -> maxWaitMillis1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
7.2 属性名称对照
| commons-dbcp 1.x | commons-dbcp2 2.x | 说明 |
|---|---|---|
maxActive | maxTotal | 最大连接数 |
maxWait | maxWaitMillis | 最大等待时间 |
removeAbandoned | removeAbandonedOnBorrow | 废弃连接回收 |
removeAbandonedTimeout | removeAbandonedOnBorrowTimeout | 废弃超时时间 |
validationQuery | validationQuery | 保持不变 |
testOnBorrow | testOnBorrow | 保持不变 |
testWhileIdle | testWhileIdle | 保持不变 |
7.3 XML 配置迁移
xml
<!-- ===== commons-dbcp 1.4 配置 ===== -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/cas_db"/>
<property name="username" value="cas_user"/>
<property name="password" value="password"/>
<property name="initialSize" value="5"/>
<property name="maxActive" value="100"/>
<property name="maxIdle" value="30"/>
<property name="minIdle" value="5"/>
<property name="maxWait" value="10000"/>
<property name="validationQuery" value="SELECT 1"/>
<property name="testOnBorrow" value="true"/>
<property name="testWhileIdle" value="true"/>
<property name="timeBetweenEvictionRunsMillis" value="30000"/>
</bean>
<!-- ===== commons-dbcp2 2.10.0 配置 ===== -->
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/cas_db?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai"/>
<property name="username" value="cas_user"/>
<property name="password" value="password"/>
<property name="initialSize" value="5"/>
<property name="maxTotal" value="100"/>
<property name="maxIdle" value="30"/>
<property name="minIdle" value="5"/>
<property name="maxWaitMillis" value="10000"/>
<property name="validationQuery" value="SELECT 1"/>
<property name="testOnBorrow" value="true"/>
<property name="testWhileIdle" value="true"/>
<property name="timeBetweenEvictionRunsMillis" value="30000"/>
<!-- commons-dbcp2 新增特性 -->
<property name="defaultAutoCommit" value="false"/>
<property name="poolPreparedStatements" value="true"/>
<property name="maxOpenPreparedStatements" value="50"/>
<property name="logAbandoned" value="true"/>
<property name="removeAbandonedOnBorrow" value="true"/>
<property name="removeAbandonedOnBorrowTimeout" value="300"/>
</bean>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
7.4 性能提升
commons-dbcp2 相比 1.x 版本在以下方面有显著提升:
- 连接创建性能:优化了连接创建的同步机制,减少锁竞争
- 空闲连接回收:改进的空闲连接检测算法,更精准地回收无效连接
- 异步关闭:支持连接的异步关闭,减少归还连接的延迟
- JMX 监控:增强的 JMX 支持,提供更详细的连接池运行时指标
- 内存管理:优化了内部数据结构的内存使用
八、前端技术栈升级
CAS 7.3 的前端技术栈进行了全面升级,引入了更现代的 UI 框架和组件库。
8.1 版本对照
| 前端组件 | CAS 5.3 | CAS 6.6 | CAS 7.3 | 变化说明 |
|---|---|---|---|---|
| Bootstrap | 3.x | 4.x | 5.3.3 | 全面重写的 CSS 框架 |
| Material Components Web | - | - | 14.0.0 | 新增 Google Material Design |
| MDI Font | - | - | 7.4.47 | 新增 Material Design Icons |
| jQuery | 2.x | 3.x | 3.7.1 | 稳定版本 |
| Font Awesome | 4.7.0 | 4.7.0 | 4.7.0 | 保持不变 |
| DataTables | - | - | 2.3.2 | 新增数据表格组件 |
| Normalize.css | - | - | 8.0.1 | 新增 CSS 重置 |
8.2 Gradle 依赖配置
groovy
dependencies {
// WebJars 依赖 - 通过包管理器引入前端资源
implementation 'org.webjars:jquery:3.7.1'
implementation 'org.webjars:bootstrap:5.3.3'
implementation 'org.webjars:font-awesome:4.7.0'
implementation 'org.webjars:datatables:2.3.2'
implementation 'org.webjars.npm:material-components-web:14.0.0'
implementation 'org.webjars.npm:mdi__font:7.4.47'
implementation 'org.webjars.npm:normalize.css:8.0.1'
}1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
8.3 Bootstrap 5 迁移要点
Bootstrap 5 相比 Bootstrap 4/3 有以下重大变化:
html
<!-- ===== Bootstrap 3 时代的典型代码 ===== -->
<div class="panel panel-default">
<div class="panel-heading">标题</div>
<div class="panel-body">内容</div>
</div>
<div class="form-group">
<label class="control-label">用户名</label>
<input type="text" class="form-control"/>
</div>
<button class="btn btn-primary">登录</button>
<!-- ===== Bootstrap 5 的对应写法 ===== -->
<div class="card">
<div class="card-header">标题</div>
<div class="card-body">内容</div>
</div>
<div class="mb-3">
<label class="form-label">用户名</label>
<input type="text" class="form-control"/>
</div>
<button class="btn btn-primary">登录</button>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Bootstrap 5 关键变化:
| 变化项 | Bootstrap 3/4 | Bootstrap 5 |
|---|---|---|
| CSS 框架基础 | Less | Sass |
| JavaScript | jQuery 依赖 | 原生 JS(无 jQuery 依赖) |
| 面板组件 | .panel | .card |
| 表单组 | .form-group | .mb-3 |
| 数据属性 | data-toggle | data-bs-toggle |
| Grid 系统 | 4 列网格 | 5 列网格(新增 xxl) |
| 颜色方案 | 主题色 | 更丰富的调色板 |
| RTL 支持 | 无 | 原生 RTL 支持 |
8.4 Material Components Web 集成
CAS 7.3 新增了 Google Material Components Web (MDC-Web) 作为可选的 UI 组件库:
html
<!-- Material Components Web 使用示例 -->
<link rel="stylesheet" href="/webjars/material-components-web/14.0.0/dist/material-components-web.min.css">
<link rel="stylesheet" href="/webjars/mdi__font/7.4.47/css/materialdesignicons.min.css">
<!-- Material Design 输入框 -->
<div class="mdc-text-field mdc-text-field--outlined">
<input type="text" id="username" class="mdc-text-field__input"
autocomplete="username" required>
<div class="mdc-notched-outline">
<div class="mdc-notched-outline__leading"></div>
<div class="mdc-notched-outline__notch">
<label for="username" class="mdc-floating-label">用户名</label>
</div>
<div class="mdc-notched-outline__trailing"></div>
</div>
</div>
<!-- Material Design 按钮 -->
<button class="mdc-button mdc-button--raised">
<span class="mdc-button__ripple"></span>
<span class="mdc-button__label">登录</span>
</button>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
8.5 Thymeleaf 模板配置
CAS 7.3 使用 Thymeleaf 作为模板引擎,配置如下:
yaml
spring:
thymeleaf:
encoding: UTF-8
cache: true # 生产环境开启缓存
mode: HTML # HTML 模板模式
template-resolver-order: 1001
2
3
4
5
6
2
3
4
5
6
九、构建工具链升级
9.1 Gradle 9.1.0 新特性
Gradle 9.1.0 带来了多项重要的构建性能和功能改进。
构建性能优化
properties
# gradle.properties - 推荐的构建优化配置
org.gradle.configureondemand=true # 按需配置
org.gradle.caching=true # 构建缓存
org.gradle.parallel=true # 并行构建
org.gradle.jvmargs=-Xms1024m -Xmx4048m -XX:TieredStopAtLevel=1
org.gradle.unsafe.configuration-cache=false # 配置缓存(Jib 不兼容)1
2
3
4
5
6
2
3
4
5
6
Gradle 9.x 关键新特性
| 特性 | 说明 | 对 CAS 构建的影响 |
|---|---|---|
| Configuration Cache | 缓存配置阶段结果 | 构建速度提升 20-50% |
| Isolated Projects | 项目隔离 | 减少不必要的重新构建 |
| Toolchain API 增强 | 更灵活的 JDK 管理 | 支持自动下载 JDK |
| Kotlin DSL 稳定 | Kotlin DSL 一等公民 | 构建脚本更安全 |
| Develocity 集成 | 构建分析平台 | 构建性能可视化 |
Jib 3.5.3 容器镜像构建
CAS 7.3 使用 Jib 插件构建 Docker 镜像,无需 Docker 守护进程:
groovy
jib {
from {
image = project.baseDockerImage // azul/zulu-openjdk:21
platforms {
imagePlatforms.each {
def given = it.split(":")
platform {
architecture = given[0]
os = given[1]
}
}
}
}
to {
image = "${project.'containerImageOrg'}/${project.'containerImageName'}:${project.version}"
credHelper = "osxkeychain"
tags = [project.version]
}
container {
creationTime = "USE_CURRENT_TIMESTAMP"
entrypoint = ['/docker/entrypoint.sh']
ports = ['80', '443', '8080', '8443', '8444', '8761', '8888', '5000']
labels = [
version: project.version,
name: project.name,
group: project.group,
org: project.containerImageOrg
]
workingDirectory = '/docker/cas/war'
}
extraDirectories {
paths {
path { from = file('src/main/jib') }
path { from = file('etc/cas'); into = '/etc/cas' }
path { from = file("build/libs"); into = "/docker/cas/war" }
}
permissions = [
'/docker/entrypoint.sh': '755'
]
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
CycloneDX 3.2.0 SBOM 生成
CAS 7.3 集成了 CycloneDX 插件,自动生成软件物料清单(SBOM):
groovy
apply plugin: "org.cyclonedx.bom"
// CycloneDX 任务与构建流程集成
tasks.named("cyclonedxBom").configure { wireOverlayDependency(delegate) }
tasks.named("cyclonedxDirectBom").configure { wireOverlayDependency(delegate) }1
2
3
4
5
2
3
4
5
SBOM 是现代软件供应链安全的重要组成部分,它记录了应用的所有依赖组件及其版本,用于:
- 安全漏洞扫描:与 Snyk、OWASP 等工具集成,自动检测已知漏洞
- 许可证合规:检查依赖的开源许可证是否符合企业政策
- 供应链审计:满足等保、SOC2 等合规要求
9.2 Java Toolchain 实战
CAS 7.3 的 Java Toolchain 配置实现了构建环境与运行环境的解耦:
properties
# gradle.properties
sourceCompatibility=21
targetCompatibility=21
jvmVendor=AMAZON # 支持: AMAZON, ADOPTIUM, JETBRAINS, MICROSOFT, ORACLE, SAP, BELLSOFT1
2
3
4
2
3
4
groovy
// build.gradle - Toolchain 配置
java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
// Gradle 会自动下载匹配的 JDK
}
}1
2
3
4
5
6
7
2
3
4
5
6
7
Toolchain 的优势:
- 构建一致性:团队成员无需手动安装指定版本的 JDK
- CI/CD 友好:构建服务器无需预装 JDK,Gradle 自动管理
- 多版本并行:同一台机器上可以同时构建不同 Java 版本的项目
- 供应商灵活:可以在不同 JVM 供应商之间自由切换
十、从传统部署到云原生
CAS 7.3 在云原生部署方面进行了全面增强,从容器化到 Kubernetes 编排,从可观测性到 Service Mesh 集成。
10.1 多阶段 Docker 构建
CAS 7.3 的 Dockerfile 采用了多阶段构建策略,显著减小最终镜像大小:
dockerfile
# 阶段1:构建
FROM gradle:9.1.0-jdk21 AS builder
WORKDIR /app
# 优化 Gradle 构建配置
RUN mkdir -p ~/.gradle \
&& echo "org.gradle.daemon=false" >> ~/.gradle/gradle.properties \
&& echo "org.gradle.configureondemand=true" >> ~/.gradle/gradle.properties
# 复制项目文件
COPY . .
# 构建:强制生成 Spring Boot 可执行 JAR
RUN chmod 750 ./gradlew \
&& ./gradlew clean bootJar -x test --parallel --no-daemon
# 提取构建产物
RUN mkdir -p /app/cas \
&& first_jar=$(ls /app/build/libs/*.jar | head -n 1) \
&& cp "$first_jar" /app/cas/cas.jar
# 阶段2:纯运行(最小化镜像)
FROM azul/zulu-openjdk:21 AS runner
WORKDIR /docker/cas/jar
# 创建 CAS 所需目录
RUN mkdir -p /etc/cas/config \
&& mkdir -p /etc/cas/services \
&& mkdir -p /etc/cas/saml \
&& chmod -R 777 /etc/cas
# 复制配置文件
COPY src/main/resources/keystore.jks /etc/cas/thekeystore
COPY src/main/resources/services /etc/cas/services
# 复制构建产物
COPY --from=builder /app/cas/cas.jar /docker/cas/jar/
# 复制启动脚本
COPY src/main/jib/docker/entrypoint.sh /docker/entrypoint.sh
RUN chmod +x /docker/entrypoint.sh
ENV PATH $PATH:$JAVA_HOME/bin:/docker/cas/jar
EXPOSE 80 443 8080 8443 8444 8761 8888 5000
ENTRYPOINT ["/docker/entrypoint.sh"]1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
多阶段构建的优势:
- 镜像体积:最终镜像仅包含 JRE 和应用 JAR,约 200-300MB(vs 单阶段约 1GB+)
- 安全性:构建阶段的所有工具链、源代码都不会出现在最终镜像中
- 构建速度:利用 Docker 层缓存,代码变更时只需重新构建最后几层
10.2 Kubernetes 部署
CAS 7.3 的 Kubernetes 部署配置示例:
yaml
# cas-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: cas-server
labels:
app: cas-server
version: v7.3.4
spec:
replicas: 3
selector:
matchLabels:
app: cas-server
template:
metadata:
labels:
app: cas-server
version: v7.3.4
spec:
containers:
- name: cas
image: apereo/cas:7.3.4
ports:
- containerPort: 8443
protocol: TCP
env:
- name: JAVA_OPTS
value: |
-XX:+UseZGC
-XX:+ZGenerational
-Xms2g
-Xmx4g
-XX:MaxGCPauseMillis=10
- name: SPRING_PROFILES_ACTIVE
value: k8s
resources:
requests:
memory: "2Gi"
cpu: "1000m"
limits:
memory: "4Gi"
cpu: "2000m"
livenessProbe:
httpGet:
path: /status/health
port: 8443
scheme: HTTPS
initialDelaySeconds: 60
periodSeconds: 30
readinessProbe:
httpGet:
path: /status/health
port: 8443
scheme: HTTPS
initialDelaySeconds: 30
periodSeconds: 10
volumeMounts:
- name: cas-config
mountPath: /etc/cas/config
- name: cas-services
mountPath: /etc/cas/services
volumes:
- name: cas-config
configMap:
name: cas-config
- name: cas-services
configMap:
name: cas-services
---
apiVersion: v1
kind: Service
metadata:
name: cas-server
spec:
type: ClusterIP
ports:
- port: 443
targetPort: 8443
protocol: TCP
selector:
app: cas-server1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
10.3 Service Mesh 集成
CAS 7.3 可以与 Istio 等 Service Mesh 集成,实现流量管理、安全通信和可观测性:
yaml
# Istio VirtualService - CAS 流量管理
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: cas-server
spec:
hosts:
- cas.example.com
gateways:
- cas-gateway
http:
- match:
- uri:
prefix: /cas/login
route:
- destination:
host: cas-server
port:
number: 443
- match:
- uri:
prefix: /cas/status
route:
- destination:
host: cas-server
port:
number: 443
retries:
attempts: 3
perTryTimeout: 5s
- fault:
delay:
percentage:
value: 1
fixedDelay: 2s
route:
- destination:
host: cas-server
subset: v7341
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
10.4 可观测性:OpenTelemetry
CAS 7.3 原生支持 OpenTelemetry,提供统一的分布式追踪、指标和日志采集:
yaml
# application.yml - OpenTelemetry 配置
management:
tracing:
sampling:
probability: 1.0
propagation:
type: w3c
otlp:
tracing:
endpoint: http://otel-collector:4318/v1/traces
metrics:
export:
otlp:
endpoint: http://otel-collector:4318/v1/metrics1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
java
// 自定义 OpenTelemetry 指标采集
@Configuration
public class CasMetricsConfiguration {
@Bean
public MeterRegistryCustomizer<MeterRegistry> casMetricsCommonTags() {
return registry -> registry.config().commonTags(
"application", "cas-server",
"version", "7.3.4"
);
}
@Bean
public TimedAspect timedAspect(MeterRegistry registry) {
return new TimedAspect(registry);
}
}
// 在认证处理器中使用 @Timed 注解
@Component
public class CustomAuthHandler {
@Timed(value = "cas.authentication.duration",
description = "认证处理耗时",
percentiles = {0.5, 0.95, 0.99})
public AuthResult authenticate(AuthenticationRequest request) {
// 认证逻辑
return AuthResult.success(request.username());
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
OpenTelemetry 三大支柱:
| 支柱 | 功能 | CAS 中的应用场景 |
|---|---|---|
| Traces(追踪) | 请求链路追踪 | 追踪认证请求从登录到出票的全链路 |
| Metrics(指标) | 运行时指标 | TGT/ST 创建速率、认证成功率、响应时间 |
| Logs(日志) | 结构化日志 | 与追踪关联的上下文日志 |
10.5 GraalVM Native Image 准备
虽然 CAS 7.3 尚未完全支持 GraalVM Native Image,但已经为此做好了架构层面的准备:
groovy
// build.gradle - GraalVM 相关配置(预留)
// CAS 7.3 的 build.gradle 中已包含 compileGraalJava 任务引用
def wireOverlayDependency = { Task t ->
["processTestResources", "compileJava", "compileGraalJava"]
.collect { tasks.findByName(it) }
.findAll { it != null }
.each { t.dependsOn(it) }
}1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
GraalVM Native Image 的潜在优势:
| 指标 | 传统 JVM 启动 | Native Image |
|---|---|---|
| 启动时间 | 10-30 秒 | 50-200 毫秒 |
| 内存占用 | 500MB-2GB | 50-200MB |
| 峰值性能 | 高(JIT 优化后) | 中(AOT 编译) |
| 容器密度 | 低 | 高 |
注意: CAS 框架大量使用反射、动态代理和运行时类加载,这些特性与 GraalVM Native Image 的 AOT 编译模型存在冲突。完整的 Native Image 支持需要 CAS 上游提供反射配置元数据。
十一、版本对比与迁移检查清单
11.1 依赖版本对比总表
以下是我们实际 CAS Overlay 项目从 6.6 升级到 7.3 的完整依赖变更清单:
| 依赖项 | CAS 6.6 版本 | CAS 7.3 版本 | 变更类型 |
|---|---|---|---|
cas-server-support-bom | 6.6.x | 7.3.4 | 大版本升级 |
spring-boot-gradle-plugin | 2.7.x | 3.5.6 | 大版本升级 |
mybatis | 3.5.6 | 3.5.16 | 小版本升级 |
mybatis-spring | 1.3.1 | 3.0.3 | 大版本升级 |
mysql-connector-java | 8.0.33 | 8.0.33 | 不变 |
commons-dbcp | 1.4 | - | 移除 |
commons-dbcp2 | - | 2.10.0 | 新增 |
pac4j-javaee | 存在 | - | 移除 |
lombok | 未指定 | 1.18.42 | 指定版本 |
jquery | 未指定 | 3.7.1 | 指定版本 |
bootstrap | 未指定 | 5.3.3 | 大版本升级 |
material-components-web | - | 14.0.0 | 新增 |
mdi__font | - | 7.4.47 | 新增 |
datatables | - | 2.3.2 | 新增 |
normalize.css | - | 8.0.1 | 新增 |
junit | 存在 | - | 移除(JUnit 5) |
jib-gradle-plugin | - | 3.5.3 | 新增 |
cyclonedx-gradle-plugin | - | 3.2.0 | 新增 |
11.2 迁移检查清单
以下是从 CAS 6.x 迁移到 7.3 的完整检查清单:
阶段一:环境准备
- [ ] 安装 JDK 21(推荐 Amazon Corretto 21 或 Azul Zulu 21)
- [ ] 升级 Gradle 到 9.1.0(或使用 Gradle Wrapper)
- [ ] 升级 IDE 到最新版本(IntelliJ IDEA 2024.1+ / Eclipse 2024-03+)
- [ ] 配置 JAVA_HOME 指向 JDK 21
- [ ] 更新 CI/CD 管道的 JDK 版本
阶段二:构建配置迁移
- [ ] 更新
gradle.properties中的版本号 - [ ] 替换
build.gradle中的依赖声明 - [ ] 移除
io.spring.gradle:dependency-management-plugin - [ ] 添加
enforcedPlatform依赖管理 - [ ] 配置 Java Toolchain
- [ ] 添加 CycloneDX SBOM 插件
- [ ] 配置 Jib 容器镜像构建
阶段三:代码迁移
- [ ] 批量替换
javax.*为jakarta.* - [ ] 更新 Spring Security 配置(移除
WebSecurityConfigurerAdapter) - [ ] 更新 MyBatis 配置(SqlSessionFactory、MapperScan)
- [ ] 替换
commons-dbcp为commons-dbcp2 - [ ] 更新数据库驱动类名(
com.mysql.jdbc.Driver->com.mysql.cj.jdbc.Driver) - [ ] 移除
pac4j-javaee依赖 - [ ] 更新自定义认证处理器
阶段四:配置迁移
- [ ] 迁移
spring.http.encoding到server.servlet.encoding - [ ] 迁移
spring.mvc.locale到spring.web.locale - [ ] 更新 Actuator 端点配置
- [ ] 禁用默认的 AcceptUsers 认证处理器
- [ ] 更新 Thymeleaf 模板中的前端资源引用
阶段五:测试与验证
- [ ] 运行单元测试
- [ ] 运行集成测试
- [ ] 验证 CAS 登录流程
- [ ] 验证 OAuth2.0 授权流程
- [ ] 验证 REST API
- [ ] 验证 SSO 单点登录/登出
- [ ] 性能测试(使用 Generational ZGC)
- [ ] 安全扫描(使用 CycloneDX SBOM)
阶段六:部署
- [ ] 构建容器镜像
- [ ] 更新 Kubernetes 部署配置
- [ ] 配置 OpenTelemetry 可观测性
- [ ] 灰度发布
- [ ] 全量发布
- [ ] 监控告警配置
十二、总结与展望
12.1 升级价值总结
CAS 7.3 + Spring Boot 3.x + Java 21 的组合,为企业级 SSO 系统带来了全方位的提升:
| 维度 | 提升内容 |
|---|---|
| 安全性 | Jakarta EE 10 安全标准、TLS 1.3、现代加密算法 |
| 性能 | Generational ZGC(GC 停顿降低 90%+)、虚拟线程(百万级并发) |
| 开发效率 | Record、Pattern Matching、Sealed Classes 减少样板代码 |
| 可维护性 | 条件装配、热刷新、组件化配置 |
| 云原生 | 容器化、Kubernetes、Service Mesh、OpenTelemetry |
| 供应链安全 | CycloneDX SBOM、依赖版本强制管理 |
12.2 未来展望
基于当前的技术趋势和 CAS 的发展路线,我们预见以下方向:
- Java 25 LTS:预计 2025 年 9 月发布的 Java 25 将带来更多语言特性和性能改进,CAS 将在后续版本中跟进
- GraalVM Native Image:随着 AOT 编译技术的成熟,CAS 的启动时间有望从秒级降到毫秒级
- WebFlux 全面支持:CAS 可能会在未来版本中提供完整的响应式编程支持
- AI 辅助认证:结合机器学习的风险感知认证(Risk-Based Authentication)将成为标配
- Passkey/FIDO2:无密码认证标准将在 CAS 中获得更深入的支持
12.3 给团队的行动建议
- 立即行动:如果当前 CAS 版本低于 6.6,建议先升级到 6.6 作为过渡
- 渐进迁移:不要试图一步到位,分阶段完成迁移
- 自动化优先:使用 OpenRewrite 等工具自动化处理命名空间迁移
- 充分测试:CAS 是核心基础设施,务必进行全面的回归测试
- 关注社区:Apereo CAS 社区非常活跃,及时关注版本更新和安全公告
版权声明: 本文为必码(bima.cc)原创技术文章,仅供学习交流。
本文内容基于实际项目源码解析整理,代码示例均为教学简化版本,仅供学习参考。
文档内容提取自项目源码与配置文件,如需获取完整项目代码,请访问 bima.cc。