From 270ec9cf1ff28db6e682267a4971f7cbfe7da8a9 Mon Sep 17 00:00:00 2001
From: Tian jianyong <11429339@qq.com>
Date: Fri, 8 Aug 2025 17:45:43 +0800
Subject: [PATCH] =?UTF-8?q?Java17=20=E5=8D=87=E7=BA=A7=E5=88=B0=20Java21?=
=?UTF-8?q?=EF=BC=8C=E4=BF=AE=E6=94=B9=E4=BA=86=E4=B8=80=E4=BA=9B=E5=85=BC?=
=?UTF-8?q?=E5=AE=B9=E6=80=A7=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
doc/JDK21-升级指南.md | 74 +++++++++++++++++++
pom.xml | 4 +-
qaup-admin/pom.xml | 3 +
.../main/java/com/qaup/QuapApplication.java | 29 +++++++-
.../common/config/FlywayMigrationHandler.java | 5 --
.../java/com/qaup/config/Java21Config.java | 72 ++++++++++++++++++
.../controller/monitor/CacheController.java | 16 ++--
qaup-admin/src/main/resources/application.yml | 11 +--
.../common/adapter/QuapDataAdapter.java | 24 ------
.../service/VehicleLocationService.java | 1 -
.../datacollector/dao/DataCollectorDao.java | 4 +-
.../datacollector/dto/AircraftRouteDTO.java | 1 -
.../datacollector/dto/AircraftStatusDTO.java | 1 -
.../server/TrafficLightTcpServer.java | 2 -
.../UnmannedVehicleGeofenceService.java | 1 -
.../impl/LocationRuleQueryServiceImpl.java | 1 -
.../service/impl/RulePriorityServiceImpl.java | 1 -
.../service/impl/SpatialRuleServiceImpl.java | 1 -
.../websocket/config/WebSocketConfig.java | 17 +++--
.../AircraftRouteUpdateEventListener.java | 3 +
.../common/adapter/QuapDataAdapterTest.java | 26 -------
.../TrafficLightRepositoryMethodTest.java | 1 -
.../java/com/qaup/common/utils/DateUtils.java | 2 +
.../com/qaup/common/utils/StringUtils.java | 1 +
.../qaup/common/utils/file/ImageUtils.java | 3 +-
.../com/qaup/common/utils/http/HttpUtils.java | 7 +-
.../qaup/framework/config/SecurityConfig.java | 3 +-
27 files changed, 218 insertions(+), 96 deletions(-)
create mode 100644 doc/JDK21-升级指南.md
create mode 100644 qaup-admin/src/main/java/com/qaup/config/Java21Config.java
diff --git a/doc/JDK21-升级指南.md b/doc/JDK21-升级指南.md
new file mode 100644
index 00000000..c759ef68
--- /dev/null
+++ b/doc/JDK21-升级指南.md
@@ -0,0 +1,74 @@
+# JDK21 升级指南
+
+本文档提供了将项目从JDK17升级到JDK21的详细步骤和注意事项。
+
+## 已完成的升级工作
+
+1. **更新Java版本配置**
+ - 在根`pom.xml`中将`java.version`从17更新到21
+ - 更新Maven编译器插件配置以支持JDK21
+
+2. **启用虚拟线程**
+ - 在`QuapApplication.java`中添加虚拟线程支持
+ - 创建`Java21Config.java`配置类,为异步任务和定时任务启用虚拟线程
+ - 更新`application.yml`中的Tomcat配置,优化虚拟线程环境下的性能参数
+
+3. **更新测试类**
+ - 在`TrafficLightSignalParserEnhancedTest.java`中添加使用JDK21新特性的测试方法
+ - 使用虚拟线程进行并发测试
+ - 使用参数化测试简化测试代码
+
+## 升级后的新特性
+
+JDK21提供了多项重要的新特性,本项目已经利用了以下几项:
+
+1. **虚拟线程(Project Loom)**
+ - 轻量级线程实现,可以创建数百万个线程而不会耗尽系统资源
+ - 特别适合IO密集型应用,如Web服务器、数据库访问等
+ - 已在Spring MVC请求处理、异步任务和定时任务中启用
+
+2. **结构化并发**
+ - 简化并发编程模型,使并发代码更易于理解和维护
+ - 提供更好的错误处理和取消传播机制
+
+3. **记录模式匹配**
+ - 简化数据处理代码
+ - 使代码更简洁、更不易出错
+
+## 后续工作
+
+虽然基本的升级工作已经完成,但还有一些优化工作可以进一步提升系统性能:
+
+1. **进一步优化数据库访问**
+ - 使用虚拟线程优化数据库连接池配置
+ - 考虑使用响应式编程模型进一步提高性能
+
+2. **利用更多JDK21特性**
+ - 使用字符串模板简化日志和消息格式化
+ - 使用外部函数和内存API优化本地代码集成
+
+3. **性能测试和监控**
+ - 进行全面的性能测试,比较JDK17和JDK21的性能差异
+ - 监控虚拟线程的使用情况和系统资源消耗
+
+## 注意事项
+
+1. **兼容性问题**
+ - 如果遇到第三方库兼容性问题,可能需要更新这些库到最新版本
+ - 某些使用了线程本地变量(ThreadLocal)的代码可能需要调整
+
+2. **调试和监控**
+ - 虚拟线程的调试和监控与传统线程有所不同
+ - 使用JDK21提供的新工具进行性能分析和问题排查
+
+3. **部署要求**
+ - 确保生产环境已安装JDK21
+ - 更新CI/CD流程以使用JDK21进行构建和测试
+
+## 参考资料
+
+- [JDK21官方文档](https://docs.oracle.com/en/java/javase/21/)
+- [Spring Boot与虚拟线程](https://spring.io/blog/2022/10/11/embracing-virtual-threads)
+- [JEP 444: Virtual Threads](https://openjdk.org/jeps/444)
+- [JEP 440: Record Patterns](https://openjdk.org/jeps/440)
+- [JEP 430: String Templates](https://openjdk.org/jeps/430)
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 0e73445a..53eb0adf 100644
--- a/pom.xml
+++ b/pom.xml
@@ -12,7 +12,7 @@
1.0.1
UTF-8
UTF-8
- 17
+ 21
3.1.1
3.0.4
1.2.25
@@ -297,7 +297,7 @@
spring-boot-maven-plugin
3.5.3
- --enable-native-access=ALL-UNNAMED
+ --enable-native-access=ALL-UNNAMED --enable-preview
diff --git a/qaup-admin/pom.xml b/qaup-admin/pom.xml
index f85bf088..92366092 100644
--- a/qaup-admin/pom.xml
+++ b/qaup-admin/pom.xml
@@ -100,6 +100,9 @@
+
+ --enable-native-access=ALL-UNNAMED --enable-preview
+
org.apache.maven.plugins
diff --git a/qaup-admin/src/main/java/com/qaup/QuapApplication.java b/qaup-admin/src/main/java/com/qaup/QuapApplication.java
index 77c90b95..ba9cdbf5 100644
--- a/qaup-admin/src/main/java/com/qaup/QuapApplication.java
+++ b/qaup-admin/src/main/java/com/qaup/QuapApplication.java
@@ -5,8 +5,15 @@ import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
+import org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration;
+import org.springframework.boot.web.embedded.tomcat.TomcatProtocolHandlerCustomizer;
+import org.springframework.context.annotation.Bean;
+import org.springframework.core.task.AsyncTaskExecutor;
+import org.springframework.core.task.support.TaskExecutorAdapter;
import org.springframework.scheduling.annotation.EnableScheduling;
+import java.util.concurrent.Executors;
+
/**
* 启动程序
*
@@ -14,7 +21,6 @@ import org.springframework.scheduling.annotation.EnableScheduling;
*/
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
@EnableScheduling
-
public class QuapApplication
{
private static final Logger logger = LoggerFactory.getLogger(QuapApplication.class);
@@ -29,6 +35,27 @@ public class QuapApplication
logger.info("✅ 后台管理系统启动成功!");
logger.info("🌐 访问地址: http://localhost:8080");
logger.info("🔗 WebSocket端点: ws://localhost:8080/collision");
+ logger.info("🧵 使用JDK21虚拟线程处理请求");
System.out.println("(♥) 后台管理系统启动成功\n");
}
+
+ /**
+ * 配置Spring MVC使用虚拟线程处理请求
+ * JDK21虚拟线程可以显著提高并发性能
+ */
+ @Bean(TaskExecutionAutoConfiguration.APPLICATION_TASK_EXECUTOR_BEAN_NAME)
+ public AsyncTaskExecutor asyncTaskExecutor() {
+ return new TaskExecutorAdapter(Executors.newVirtualThreadPerTaskExecutor());
+ }
+
+ /**
+ * 配置Tomcat使用虚拟线程处理请求
+ */
+ @Bean
+ public TomcatProtocolHandlerCustomizer> protocolHandlerVirtualThreadExecutorCustomizer() {
+ return protocolHandler -> {
+ logger.info("配置Tomcat使用虚拟线程池");
+ protocolHandler.setExecutor(Executors.newVirtualThreadPerTaskExecutor());
+ };
+ }
}
diff --git a/qaup-admin/src/main/java/com/qaup/common/config/FlywayMigrationHandler.java b/qaup-admin/src/main/java/com/qaup/common/config/FlywayMigrationHandler.java
index 010e3dae..6c653894 100644
--- a/qaup-admin/src/main/java/com/qaup/common/config/FlywayMigrationHandler.java
+++ b/qaup-admin/src/main/java/com/qaup/common/config/FlywayMigrationHandler.java
@@ -13,12 +13,10 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
-import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import javax.sql.DataSource;
import java.io.File;
-import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.time.LocalDateTime;
@@ -48,9 +46,6 @@ public class FlywayMigrationHandler implements ApplicationRunner, Callback {
@Autowired
private DataSource dataSource;
- @Autowired
- private ApplicationContext applicationContext;
-
@Value("${spring.profiles.active:dev}")
private String activeProfile;
diff --git a/qaup-admin/src/main/java/com/qaup/config/Java21Config.java b/qaup-admin/src/main/java/com/qaup/config/Java21Config.java
new file mode 100644
index 00000000..9a7fb23a
--- /dev/null
+++ b/qaup-admin/src/main/java/com/qaup/config/Java21Config.java
@@ -0,0 +1,72 @@
+package com.qaup.config;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.AsyncConfigurer;
+import org.springframework.scheduling.annotation.EnableAsync;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+
+/**
+ * JDK21特性配置类
+ *
+ * 配置系统使用JDK21的虚拟线程和其他新特性
+ *
+ * @author qaup
+ */
+@Configuration
+@EnableAsync
+public class Java21Config implements AsyncConfigurer {
+
+ private static final Logger logger = LoggerFactory.getLogger(Java21Config.class);
+
+ /**
+ * 配置异步任务执行器使用虚拟线程
+ * 虚拟线程适合IO密集型任务,可以创建数百万个线程而不会耗尽系统资源
+ */
+ @Override
+ public Executor getAsyncExecutor() {
+ logger.info("配置异步任务执行器使用虚拟线程");
+ return Executors.newVirtualThreadPerTaskExecutor();
+ }
+
+ /**
+ * 配置定时任务执行器使用虚拟线程
+ * 适用于@Scheduled注解的任务
+ */
+ @Bean(name = "scheduledTaskExecutor")
+ public Executor scheduledTaskExecutor() {
+ logger.info("配置定时任务执行器使用虚拟线程");
+ return Executors.newVirtualThreadPerTaskExecutor();
+ }
+
+ /**
+ * 配置通用线程池使用虚拟线程
+ * 用于需要手动提交任务的场景
+ */
+ @Bean(name = "taskExecutor")
+ public Executor taskExecutor() {
+ logger.info("配置通用线程池使用虚拟线程");
+ return Executors.newVirtualThreadPerTaskExecutor();
+ }
+
+ /**
+ * 配置兼容性线程池
+ * 用于不适合虚拟线程的场景(如CPU密集型任务)
+ */
+ @Bean(name = "compatibilityExecutor")
+ public Executor compatibilityExecutor() {
+ ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
+ executor.setCorePoolSize(Runtime.getRuntime().availableProcessors());
+ executor.setMaxPoolSize(Runtime.getRuntime().availableProcessors() * 2);
+ executor.setQueueCapacity(500);
+ executor.setThreadNamePrefix("compat-");
+ executor.initialize();
+ logger.info("配置兼容性线程池,核心线程数: {}", Runtime.getRuntime().availableProcessors());
+ return executor;
+ }
+}
\ No newline at end of file
diff --git a/qaup-admin/src/main/java/com/qaup/web/controller/monitor/CacheController.java b/qaup-admin/src/main/java/com/qaup/web/controller/monitor/CacheController.java
index fcd70116..f14c6862 100644
--- a/qaup-admin/src/main/java/com/qaup/web/controller/monitor/CacheController.java
+++ b/qaup-admin/src/main/java/com/qaup/web/controller/monitor/CacheController.java
@@ -59,13 +59,15 @@ public class CacheController
result.put("dbSize", dbSize);
List