Files
lottery/.trae/documents/nine_surplus-springboot升级方案.md
T
feng0207 3fc4dcc777 initial commit: lottery 项目集(三工程统一管理)
- apps/lotteryServer, lotteryCapture, lotteryOpen 三个业务工程
- 忽略 archive/, tools/, infra/data/ 大目录与敏感配置文件
- 移除 lotteryServer 原嵌套 git,并入顶层统一管理
2026-09-17 19:03:32 +08:00

99 lines
7.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# nine_surplus 升级方案:Spring Boot 化 + 可执行 Jar + JDK 升级
## Context(背景与目标)
`nine_surplus`(11.1 万行、900 个 Java 文件)目前是一个基于 **Spring 4.1 + SpringMVC + Hibernate 4.2 + javax.servlet/JSP + 外部 Tomcat 8.5** 的 Web 应用,技术栈停留在 2013 年。当前部署方式是打成 `lotteryServer.war` 丢进 `apache-tomcat-8.5.100`,且此项目还在本机用 JDK8 运行。
用户明确诉求:
1. **集成 Spring Boot**,引入内嵌 Tomcat
2. **打包成可一键执行 `java -jar` 的 jar**,不再依赖外部 Tomcat
3. **JDK 升级到 11/17**
4. 本次只升级 `nine_surplus`,另外两个模块(lotteryCapture/lotteryOpen)不动
推荐技术选型(已和用户目标对齐):
- **Spring Boot 2.7.x**(Spring 5.3 + javax.servlet 命名空间,与现有 `javax.*` 代码完全兼容,避免 11 万行改名)
- **Hibernate 5.6.x**(Boot 2.7 配套,替换已从 spring-orm 移除的 hibernate4 支持)
- **内嵌 Tomcat 9.x**(由 spring-boot-starter-web 提供)
- **JDK 11**(先升 11 稳妥运行,17 作为后续可选)
- **JSP/HTML 页面与现有 Spring XML 配置尽量保留**,降低改动面
> 注意:不采用 Spring Boot 3(jakarta 命名空间),否则全部 `javax.*` 要改名,风险不可控。
---
## 升级要点(改造点梳理)
### 1. 保留不动的内容(大块存量)
- **59 个 JSP + 119 个 HTML 静态页**,原样保留(Boot 内嵌 Tomcat 可直接加载)
- **spring-config.xml / spring-mvc.xml** 的 XML bean 定义,通过主类 `@ImportResource` 引导加载,不改业务 bean
- **6 个支付/加密 system scope 黑盒 jar**:`cryptix-jce-provider`、`lzma-4.63-jio`、`dinpayRsaSignAPI`、`beecloud-java-sdk`、`yst_api`、`lzma`。这些是黑盒支付 SDK,改造时**不碰它们的实现**,仅确保能打进可执行 jar 的 classpath
### 2. 必须修改的部分
#### A. pom.xml 重构
| 项 | 现状 | 改后 |
|----|------|------|
| packaging | `war` | `jar` |
| parent | 无 | `spring-boot-starter-parent:2.7.x` |
| spring | 4.1.0.RELEASE | 由 Boot 2.7 管理(Spring 5.3.x,去掉显式 `<spring.version>`) |
| hibernate | 4.2.13.Final | 5.6.x(Boot 管理,去掉 `<hibernate.version>`) |
| 依赖 | 各 spring/hibernate 手动声明 | 合并为 starter:`spring-boot-starter-web`、`spring-boot-starter-data-jpa` 或保留 jdbc/hibernate;redis 用 `spring-boot-starter-data-redis` 或保留 spring-data-redis+jedis |
| system scope jar | cryptix/lzma/dinpay/beecloud/yst | 保留,但需处理打入 jar(Boot 默认不打包 system scope,需 `maven-jar-plugin` 或 spring-boot-maven-plugin 的 exclude/include 配置) |
| maven-jar-plugin mainClass | 无 | 填 `com.xxx.LotteryServerApplication` |
| Web 插件 | `maven-war-plugin` / `tomcat7-maven-plugin` | 移除,改用 `spring-boot-maven-plugin` |
**关键坑**:`LocalSessionFactoryBean` 从 `org.springframework.orm.hibernate4` 改为 `org.springframework.orm.hibernate5`。
#### B. 新增 Spring Boot 启动主类
新建 `LotteryServerApplication`(`@SpringBootApplication` + `@ImportResource("classpath:config/spring/spring-config.xml")`),并在其中:
- `@Bean` 配置 spring-mvc 的 DispatcherServlet 映射(或通过配置类 `implements WebMvcConfigurer` 引入 spring-mvc.xml)
- `@Bean` 注册 CharacterEncodingFilter、springSessionRepositoryFilter(替代 web.xml 中的 filter)
- 可选:让主类 `extends SpringBootServletInitializer` 以保留双部署能力
#### C. Hibernate 5 适配(核心工作量)
集中在 DAO 基类,量小但关键:
- [HibernateSuperDao.java](file:///c:/data/src/lottery/nine_surplus/nine_surplus/src/main/java/javautils/jdbc/hibernate/HibernateSuperDao.java)
- [HibernateSuperReadDao.java](file:///c:/data/src/lottery/nine_surplus/nine_surplus/src/main/java/javautils/jdbc/hibernate/HibernateSuperReadDao.java)
- 关注点:`getCurrentSession()`、`createCriteria`、`sessionFactory` 注入、事务管理器适配(`HibernateTransactionManager` → hibernate5 包)
- spring-config.xml 中 3 个 `LocalSessionFactoryBean`(write/read/autoLoad)的 class 改为 hibernate5,`hibernate.cache.provider_class` 等属性检查
#### D. WebSocket 适配
- [WebSocketConfig.java](file:///c:/data/src/lottery/nine_surplus/nine_surplus/src/main/java/lottery/web/websocket/WebSocketConfig.java) 用 `@EnableWebSocket`(Spring 自带,非原生 javax.websocket),Boot 2.7 兼容,基本无需改;仅确认 handler 依赖的容器对象注入方式
#### E. 资源/配置加载
- `EncryptPropertyPlaceholderConfigurer`(显式读取 `.properties` + 解密)在 Boot 下需适配为 `PropertySourcesPlaceholderConfigurer` 风格或保留自定义类,确认 `${...}` 占位符在 Boot 环境正常解析
- 确认 `config/datasource/*.properties`、`config/hibernate/*` 的 classpath 路径在打包 jar 后仍在类路径上
---
## 推荐实施步骤(分批执行)
1. **备份**:先对 `nine_surplus` 目录做完整备份 / 用 git 分支,确保可回滚
2. **pom 改造 + 主类骨架**:改 packaging、引入 Boot parent/starter、新增 `LotteryServerApplication`,先让应用能`mvn spring-boot:run` 起来(不急着全功能)
3. **Hibernate 5 适配**:替换 DAO 基类与 spring-config 中的 hibernate4→hibernate5,编译通过
4. **Filter/DispatcherServlet 注册**:把 web.xml 里的 filter、servlet 迁移到 Boot 主类/配置类
5. **system jar 打包确认**:验证支付 SDK 能被可执行 jar 正确加载
6. **JDK 11 验证**:`mvn clean package` 产出可执行 jar,`java -jar lotteryServer.jar` 启动成功,访问登录页
7. **回归测试**:登录、下单、余额/报表等核心链路 + Redis 会话 + WebSocket
## 代表性关键文件
- `nine_surplus/pom.xml`(重构)
- `nine_surplus/src/main/webapp/WEB-INF/web.xml`(配置迁移参照,可删除)
- `nine_surplus/src/main/resources/config/spring/spring-config.xml`、`spring-mvc.xml`(保留 + hibernate5 适配)
- 新增 `LotteryServerApplication.java`
- `javautils/jdbc/hibernate/HibernateSuperDao.java`、`HibernateSuperReadDao.java`(Hibernate5 适配)
- `lottery/web/websocket/WebSocketConfig.java`(确认兼容)
---
## 验证方式
1. `mvn -f pom.xml clean package` 成功产出可执行 jar
2. `java -jar target/lotteryServer.jar`(JDK11)启动,无 ClassNotFound/NoSuchMethod 异常
3. 浏览器访问 `http://localhost:8080/`(或配置端口)能返回登录页(原 war 是 8080)
4. 确认 Redis 会话、WebSocket、支付回调等核心链路可用
5. 用 `jvisualvm`/启动日志确认内嵌 Tomcat 正常监听端口
## 风险与明确边界
- **不会做**:不搬到 Spring Boot 3 / jakarta、不迁移 Thymeleaf、不重写 11 万行业务代码、不处理另两个模块
- **高危点**:Hibernate 4→5 的 API 差异(主要在 2 个 DAO 基类 + 事务管理器)、system 支付 jar 的兼容性、`EncryptPropertyPlaceholderConfigurer` 解密在 Boot 环境的解析
- **如遇 system jar 在 JDK11 上不兼容**(黑盒无从修改):降级方案是仅 JDK 升级到 11、保留 war,Boot 化分阶段单独进行,避免一次全上