# 应用结构
**本文引用的文件**
- [FmsApiApplication.java](file://fms-api/src/main/java/cn/g3soft/fmsapi/FmsApiApplication.java)
- [pom.xml](file://fms-api/pom.xml)
- [application.yaml](file://fms-api/src/main/resources/application.yaml)
- [AuthProperties.java](file://fms-api/src/main/java/cn/g3soft/fmsapi/config/AuthProperties.java)
- [FileStorageProperties.java](file://fms-api/src/main/java/cn/g3soft/fmsapi/config/FileStorageProperties.java)
- [JacksonConfig.java](file://fms-api/src/main/java/cn/g3soft/fmsapi/config/JacksonConfig.java)
- [JwtAuthFilter.java](file://fms-api/src/main/java/cn/g3soft/fmsapi/config/JwtAuthFilter.java)
- [AuthController.java](file://fms-api/src/main/java/cn/g3soft/fmsapi/controller/AuthController.java)
- [DataController.java](file://fms-api/src/main/java/cn/g3soft/fmsapi/controller/DataController.java)
- [AuthService.java](file://fms-api/src/main/java/cn/g3soft/fmsapi/service/AuthService.java)
- [DataService.java](file://fms-api/src/main/java/cn/g3soft/fmsapi/service/DataService.java)
- [OrgDataSourceFactory.java](file://fms-api/src/main/java/cn/g3soft/fmsapi/database/OrgDataSourceFactory.java)
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖分析](#依赖分析)
7. [性能考虑](#性能考虑)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)
## 简介
本文件面向FMS后端(Spring Boot)应用,系统性说明其启动流程、配置机制与分层架构。重点包括:
- 主类 FmsApiApplication 的职责与启动时序
- Snowflake ID 生成器的初始化与使用
- 分层包结构与职责划分(controller、service、database、config)
- Maven 构建与依赖管理(Spring Boot 版本、核心依赖、插件)
- application.yaml 配置项含义与扩展方式
- 关键请求的时序图与组件交互关系图
## 项目结构
后端模块位于 fms-api,采用典型的 Spring Boot 分层组织:
- controller:对外暴露 REST 接口,负责参数校验与响应封装
- service:业务编排与领域逻辑
- database:多租户/多机构数据源路由与连接池管理
- config:配置绑定、序列化、安全过滤等横切能力
- resources:应用配置文件与迁移脚本
```mermaid
graph TB
subgraph "控制器层"
AC["AuthController"]
DC["DataController"]
end
subgraph "服务层"
AS["AuthService"]
DS["DataService"]
end
subgraph "数据库层"
ODF["OrgDataSourceFactory"]
end
subgraph "配置层"
AP["AuthProperties"]
FP["FileStorageProperties"]
JC["JacksonConfig"]
JAF["JwtAuthFilter"]
end
subgraph "入口与配置"
APP["FmsApiApplication"]
CFG["application.yaml"]
end
AC --> AS
DC --> DS
AS --> ODF
DS --> ODF
APP --> JC
APP --> JAF
AP -.-> AS
FP -.-> AC
CFG -.-> APP
```
图表来源
- [FmsApiApplication.java:9-18](file://fms-api/src/main/java/cn/g3soft/fmsapi/FmsApiApplication.java#L9-L18)
- [AuthController.java:19-55](file://fms-api/src/main/java/cn/g3soft/fmsapi/controller/AuthController.java#L19-L55)
- [DataController.java:19-94](file://fms-api/src/main/java/cn/g3soft/fmsapi/controller/DataController.java#L19-L94)
- [AuthService.java:19-84](file://fms-api/src/main/java/cn/g3soft/fmsapi/service/AuthService.java#L19-L84)
- [DataService.java:17-69](file://fms-api/src/main/java/cn/g3soft/fmsapi/service/DataService.java#L17-L69)
- [OrgDataSourceFactory.java:9-51](file://fms-api/src/main/java/cn/g3soft/fmsapi/database/OrgDataSourceFactory.java#L9-L51)
- [AuthProperties.java:7-27](file://fms-api/src/main/java/cn/g3soft/fmsapi/config/AuthProperties.java#L7-L27)
- [FileStorageProperties.java:5-67](file://fms-api/src/main/java/cn/g3soft/fmsapi/config/FileStorageProperties.java#L5-L67)
- [JacksonConfig.java:8-17](file://fms-api/src/main/java/cn/g3soft/fmsapi/config/JacksonConfig.java#L8-L17)
- [application.yaml:1-34](file://fms-api/src/main/resources/application.yaml#L1-L34)
章节来源
- [FmsApiApplication.java:9-18](file://fms-api/src/main/java/cn/g3soft/fmsapi/FmsApiApplication.java#L9-L18)
- [application.yaml:1-34](file://fms-api/src/main/resources/application.yaml#L1-L34)
## 核心组件
- 启动入口与全局配置扫描
- 主类通过注解启用自动装配与配置属性扫描,并在启动前初始化 Snowflake ID 生成器的工作节点标识
- 认证与授权
- 基于 JWT 的登录流程,包含用户校验、令牌签发与会话登记
- 数据访问
- 提供通用数据加载、分页、元数据描述与 SQL 执行能力
- 支持按机构维度创建与管理 Druid 连接池
- 配置绑定
- 将 application.yaml 中的认证、文件存储、数据库连接池等配置映射为类型安全的对象
- 序列化
- 统一 Long 类型序列化为字符串,避免前端精度丢失
章节来源
- [FmsApiApplication.java:9-18](file://fms-api/src/main/java/cn/g3soft/fmsapi/FmsApiApplication.java#L9-L18)
- [AuthController.java:19-55](file://fms-api/src/main/java/cn/g3soft/fmsapi/controller/AuthController.java#L19-L55)
- [AuthService.java:19-84](file://fms-api/src/main/java/cn/g3soft/fmsapi/service/AuthService.java#L19-L84)
- [DataController.java:19-94](file://fms-api/src/main/java/cn/g3soft/fmsapi/controller/DataController.java#L19-L94)
- [DataService.java:17-69](file://fms-api/src/main/java/cn/g3soft/fmsapi/service/DataService.java#L17-L69)
- [OrgDataSourceFactory.java:9-51](file://fms-api/src/main/java/cn/g3soft/fmsapi/database/OrgDataSourceFactory.java#L9-L51)
- [AuthProperties.java:7-27](file://fms-api/src/main/java/cn/g3soft/fmsapi/config/AuthProperties.java#L7-L27)
- [FileStorageProperties.java:5-67](file://fms-api/src/main/java/cn/g3soft/fmsapi/config/FileStorageProperties.java#L5-L67)
- [JacksonConfig.java:8-17](file://fms-api/src/main/java/cn/g3soft/fmsapi/config/JacksonConfig.java#L8-L17)
## 架构总览
下图展示从请求进入到返回的整体交互路径,涵盖认证、数据读取与 Snowflake ID 生成。
```mermaid
sequenceDiagram
participant C as "客户端"
participant W as "Web容器"
participant A as "AuthController"
participant S as "AuthService"
participant D as "DbUtils/DataSource"
participant J as "Jwt工具"
participant I as "IdGenerator"
C->>W : HTTP POST /api/auth/login
W->>A : 分发到登录接口
A->>S : 调用登录(orgId, userId, password, request)
S->>D : 查询并验证用户
D-->>S : 用户信息
S->>J : 生成JWT(含orgId, sessionId)
J-->>S : token
S->>I : 可选记录会话ID(由注册表管理)
S-->>A : 返回{token, orgid, user}
A-->>C : 200 + 统一响应体
```
图表来源
- [AuthController.java:26-55](file://fms-api/src/main/java/cn/g3soft/fmsapi/controller/AuthController.java#L26-L55)
- [AuthService.java:34-84](file://fms-api/src/main/java/cn/g3soft/fmsapi/service/AuthService.java#L34-L84)
## 详细组件分析
### 启动流程与Snowflake ID初始化
- 启动入口职责
- 启用 Spring Boot 自动装配与配置属性扫描
- 在应用上下文启动前设置 Snowflake ID 生成器的工作节点标识
- 启动时序
- 解析命令行参数与环境变量
- 初始化配置绑定(@ConfigurationPropertiesScan)
- 注册 Jackson 自定义序列化模块
- 启动内嵌 Web 服务器并暴露端口与上下文路径
```mermaid
flowchart TD
Start(["进程启动"]) --> InitOptions["初始化ID生成器选项
设置工作节点ID"]
InitOptions --> RunSpring["SpringApplication.run()"]
RunSpring --> ScanProps["扫描配置属性类"]
ScanProps --> RegisterBeans["注册Jackson/过滤器等Bean"]
RegisterBeans --> StartServer["启动Web服务器
端口/上下文路径"]
StartServer --> Ready(["应用就绪"])
```
图表来源
- [FmsApiApplication.java:9-18](file://fms-api/src/main/java/cn/g3soft/fmsapi/FmsApiApplication.java#L9-L18)
- [JacksonConfig.java:8-17](file://fms-api/src/main/java/cn/g3soft/fmsapi/config/JacksonConfig.java#L8-L17)
- [application.yaml:1-4](file://fms-api/src/main/resources/application.yaml#L1-L4)
章节来源
- [FmsApiApplication.java:9-18](file://fms-api/src/main/java/cn/g3soft/fmsapi/FmsApiApplication.java#L9-L18)
- [application.yaml:1-4](file://fms-api/src/main/resources/application.yaml#L1-L4)
### 认证流程(登录)
- 控制器接收登录请求,提取机构、账号与密码
- 服务层查询用户、校验密码、生成JWT并登记活跃会话
- 统一响应封装成功或失败结果
```mermaid
sequenceDiagram
participant Client as "客户端"
participant AuthCtrl as "AuthController"
participant AuthSvc as "AuthService"
participant Db as "DbUtils/DataSource"
participant Jwt as "JwtUtils"
participant Session as "ActiveSessionRegistry"
Client->>AuthCtrl : POST /api/auth/login
AuthCtrl->>AuthSvc : login(orgId, userId, password, request)
AuthSvc->>Db : 查询用户信息
Db-->>AuthSvc : 用户记录
AuthSvc->>Jwt : generateToken(accountId, orgId, sessionId)
Jwt-->>AuthSvc : token
AuthSvc->>Session : activate(orgId, accountId, sessionId)
AuthSvc-->>AuthCtrl : {token, orgid, user}
AuthCtrl-->>Client : ApiResponse.success(...)
```
图表来源
- [AuthController.java:26-55](file://fms-api/src/main/java/cn/g3soft/fmsapi/controller/AuthController.java#L26-L55)
- [AuthService.java:34-84](file://fms-api/src/main/java/cn/g3soft/fmsapi/service/AuthService.java#L34-L84)
章节来源
- [AuthController.java:26-55](file://fms-api/src/main/java/cn/g3soft/fmsapi/controller/AuthController.java#L26-L55)
- [AuthService.java:34-84](file://fms-api/src/main/java/cn/g3soft/fmsapi/service/AuthService.java#L34-L84)
### 数据访问与分页
- DataController 暴露数据加载、SQL直查、分页、元数据描述与ID/编码生成接口
- DataService 负责参数校验、分页计算与底层 DbUtils 调用
- 分页结果包含行数据、总数与页码信息
```mermaid
flowchart TD
In(["请求进入 /data/*"]) --> Route{"路由分支"}
Route --> |loaddata| Ld["DataService.loadData()"]
Route --> |loaddatabysql| Sql["DataService.loadDataBySql()"]
Route --> |page| Pg["DataService.page()"]
Route --> |describe| Desc["DataService.describe()"]
Route --> |nextid| Id["IdGenerator.nextId()"]
Route --> |nextcode| Code["DataSaveService.nextCode()"]
Ld --> Out(["统一响应"])
Sql --> Out
Pg --> Out
Desc --> Out
Id --> Out
Code --> Out
```
图表来源
- [DataController.java:29-94](file://fms-api/src/main/java/cn/g3soft/fmsapi/controller/DataController.java#L29-L94)
- [DataService.java:26-69](file://fms-api/src/main/java/cn/g3soft/fmsapi/service/DataService.java#L26-L69)
章节来源
- [DataController.java:29-94](file://fms-api/src/main/java/cn/g3soft/fmsapi/controller/DataController.java#L29-L94)
- [DataService.java:26-69](file://fms-api/src/main/java/cn/g3soft/fmsapi/service/DataService.java#L26-L69)
### 多机构数据源与连接池
- OrgDataSourceFactory 根据机构ID与配置动态创建 Druid 连接池
- 连接池参数来源于配置类,包含初始大小、最大活动数、空闲检测、保活策略等
- 初始化失败时关闭资源并抛出异常,便于上层感知
```mermaid
classDiagram
class OrgDataSourceFactory {
+create(orgId, config) DruidDataSource
}
class OrgDatabaseProperties {
+Pool pool
}
class DruidDataSource {
+init()
+setKeepAlive(flag)
+setTimeBetweenEvictionRunsMillis(ms)
}
OrgDataSourceFactory --> OrgDatabaseProperties : "读取连接池配置"
OrgDataSourceFactory --> DruidDataSource : "创建并初始化"
```
图表来源
- [OrgDataSourceFactory.java:9-51](file://fms-api/src/main/java/cn/g3soft/fmsapi/database/OrgDataSourceFactory.java#L9-L51)
章节来源
- [OrgDataSourceFactory.java:9-51](file://fms-api/src/main/java/cn/g3soft/fmsapi/database/OrgDataSourceFactory.java#L9-L51)
### 配置绑定与序列化
- 认证配置:fms.auth 前缀下的密钥与过期时间
- 文件存储配置:fms.file 前缀下的本地/云存储参数
- Jackson 配置:Long 类型统一序列化为字符串,避免前端精度问题
章节来源
- [AuthProperties.java:7-27](file://fms-api/src/main/java/cn/g3soft/fmsapi/config/AuthProperties.java#L7-L27)
- [FileStorageProperties.java:5-67](file://fms-api/src/main/java/cn/g3soft/fmsapi/config/FileStorageProperties.java#L5-L67)
- [JacksonConfig.java:8-17](file://fms-api/src/main/java/cn/g3soft/fmsapi/config/JacksonConfig.java#L8-L17)
## 依赖分析
- 构建与运行环境
- Java 版本:21
- Spring Boot 父工程版本:4.1.0
- 核心依赖
- Web:spring-boot-starter-webmvc
- 数据库:spring-boot-starter-jdbc、Druid 连接池、MSSQL JDBC
- 安全:jjwt 系列(API/实现/Jackson)
- 其他:Jackson Databind、UA Parser、IP2Region
- 插件
- spring-boot-maven-plugin 用于打包可执行 Jar
```mermaid
graph LR
App["fms-api"] --> Web["spring-boot-starter-webmvc"]
App --> Jdbc["spring-boot-starter-jdbc"]
App --> Druid["druid"]
App --> Mssql["mssql-jdbc"]
App --> JJWT["jjwt-api/impl/jackson"]
App --> Jackson["jackson-databind"]
App --> UAP["uap-java"]
App --> IP2R["ip2region"]
```
图表来源
- [pom.xml:32-96](file://fms-api/pom.xml#L32-L96)
章节来源
- [pom.xml:5-10](file://fms-api/pom.xml#L5-L10)
- [pom.xml:29-31](file://fms-api/pom.xml#L29-L31)
- [pom.xml:32-96](file://fms-api/pom.xml#L32-L96)
- [pom.xml:98-105](file://fms-api/pom.xml#L98-L105)
## 性能考虑
- 连接池调优
- 初始大小与最小空闲设为 0,按需增长;最大活动连接限制并发
- 开启空闲连接保活与定期探测,降低云环境 NAT/防火墙回收导致的连接失效
- 鉴权与序列化
- JWT 无状态校验,减少服务端状态压力
- Long 序列化为字符串,避免前端精度损失与额外转换开销
- 数据访问
- 分页查询减少单次传输数据量
- 视图/SQL 直查需结合索引与查询计划优化
[本节为通用指导,不直接分析具体文件]
## 故障排查指南
- 启动阶段
- 检查端口与上下文路径是否冲突
- 确认 Snowflake 工作节点ID已正确设置
- 认证失败
- 核对机构码、账号、密码是否为空或不匹配
- 查看登录日志记录原因(账号不存在、密码错误)
- 数据访问异常
- 检查对应机构的数据源配置与连接池参数
- 关注连接获取失败时的重试与保活策略
- 序列化问题
- 若前端出现大整数精度丢失,确认 Jackson 模块已生效
章节来源
- [application.yaml:1-34](file://fms-api/src/main/resources/application.yaml#L1-L34)
- [AuthController.java:26-55](file://fms-api/src/main/java/cn/g3soft/fmsapi/controller/AuthController.java#L26-L55)
- [AuthService.java:34-84](file://fms-api/src/main/java/cn/g3soft/fmsapi/service/AuthService.java#L34-L84)
- [OrgDataSourceFactory.java:9-51](file://fms-api/src/main/java/cn/g3soft/fmsapi/database/OrgDataSourceFactory.java#L9-L51)
- [JacksonConfig.java:8-17](file://fms-api/src/main/java/cn/g3soft/fmsapi/config/JacksonConfig.java#L8-L17)
## 结论
该 FMS 后端采用清晰的 Spring Boot 分层架构,通过配置绑定与连接池工厂实现灵活的运行时配置与多机构数据源管理。认证流程基于 JWT,数据访问提供通用能力并支持分页与元数据描述。整体设计兼顾可扩展性与可维护性,适合在企业级场景中持续演进。
[本节为总结性内容,不直接分析具体文件]
## 附录
- 关键配置项说明(来自 application.yaml)
- server.port/server.servlet.context-path:服务监听端口与上下文路径
- spring.application.name:应用名称
- fms.auth.jwt-secret/jwt-expiration:JWT 签名密钥与有效期
- fms.database.config-dir/pool.*:多机构数据库配置目录与连接池参数
- fms.file.storage-type/local.*:本地文件存储目录与URL前缀
- fms.file.oss.g3oss-url:OSS 服务地址
章节来源
- [application.yaml:1-34](file://fms-api/src/main/resources/application.yaml#L1-L34)