# m-server 轻量级Web开发框架 **Repository Path**: huhuanan/m-server ## Basic Information - **Project Name**: m-server 轻量级Web开发框架 - **Description**: 一个轻量级、高性能的 Java Web 全栈框架。从零构建,不依赖 Spring 等第三方 Web 框架,仅使用 JDK 8 + MySQL 驱动 + FastJSON2 三个依赖,即可提供完整的 Web 服务器、ORM、缓存、任务调度能力。 - **Primary Language**: Java - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-02-24 - **Last Updated**: 2026-05-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # m-server 一个轻量级、高性能的 Java Web 全栈框架。从零构建,不依赖 Spring 等第三方 Web 框架,仅使用 **JDK 8 + MySQL 驱动 + FastJSON2** 三个依赖,即可提供完整的 Web 服务器、ORM、缓存、任务调度能力。 ## 特性 - **自研 Web 服务器** — 基于 Socket 的 HTTP/HTTPS 服务器,内置线程池与 SSL/TLS 支持 - **注解驱动 ORM** — 通过 `@TableMeta`、`@FieldMeta` 等注解定义模型,自动建表,支持联表查询与多数据源 - **Action 路由体系** — `@ActionRequest` + `@RequestMethod` 注解映射 URL 到 Java 方法,支持参数绑定、声明式事务 - **三级缓存架构** — 单键、双键、列表三种缓存类型,支持分布式节点分区与自动过期清理 - **灵活任务调度** — `@TaskStartRunMeta`(间隔执行)和 `@TaskTimerRunMeta`(Cron 定时)两种调度模式 - **安全防护** — URL 白名单、Referer 校验、授权头匹配、敏感字段自动过滤 - **极简部署** — 单 JAR + lib 目录,`java -jar` 一行命令启动 ## 目录 - [技术栈](#技术栈) - [功能概览](#功能概览) - [项目架构](#项目架构) - [整体分层](#整体分层) - [请求处理流程](#请求处理流程) - [核心模块详解](#核心模块详解) - [快速开始](#快速开始) - [环境与配置](#环境与配置) - [定义 Model](#定义-model) - [定义 Action](#定义-action) - [定义 Service](#定义-service) - [定义定时任务](#定义定时任务) - [配置路由与访问控制](#配置路由与访问控制) - [使用缓存](#使用缓存) - [引用框架](#引用框架) - [框架优势](#框架优势) ## 技术栈 | 组件 | 选型 | 说明 | |------|------|------| | JDK | 1.8+ | 最低版本要求 | | Web 服务器 | 自研 Socket 服务器 | 固定线程池,支持 HTTP / HTTPS | | JSON | FastJSON2 2.0.61 | 请求解析与序列化 | | 数据库 | MySQL 8.0 | 自研连接池与 ORM 映射 | | 构建工具 | Maven | 打包与依赖管理 | Maven 依赖仅两项: ```xml mysql mysql-connector-java 8.0.33 com.alibaba.fastjson2 fastjson2 2.0.61 ``` ## 功能概览 ### Web 服务器 | 功能 | 说明 | |------|------| | HTTP/HTTPS | 基于 ServerSocket,配置 JKS 证书即启用 HTTPS | | 线程池 | 固定大小线程池处理并发连接,池大小根据数据库连接数自动计算 | | 请求解析 | 支持 GET/POST/PUT/DELETE,解析 JSON、URL 编码、Multipart/FormData | | 响应输出 | 支持 JSON 响应、文件下载、字节流输出、页面重定向 | | 会话管理 | ThreadLocal 隔离的 Session,同时支持 Cookie 和 Authorization Header | ### ORM 模型层 | 功能 | 说明 | |------|------| | 注解建模 | `@TableMeta` 定义表,`@FieldMeta` 定义列,`@LinkTableMeta` 定义外键关联 | | 自动建表 | 启动时扫描 Model 注解,自动创建/更新数据库表结构 | | CRUD 操作 | `saveModel`(自动判断新增/修改)、`insertModel`、`updateModel`、`deleteModel`,均支持批量 | | 条件查询 | `QueryCondition` 构建器支持 `eq`、`like`、`in`、`between`、`isNotNull` 等条件 | | 分页查询 | `QueryPage` 支持自动分页,返回数据列表与总数 | | 联表查询 | `@LinkTableMeta` 自动 JOIN 关联表,支持多级关联 | | 自定义 SQL | `ModelQuery` 流式 API 支持自定义字段表达式与原生 SQL 片段 | | 多数据源 | 每个 Model 通过 `@TableMeta(db="xxx")` 指定不同数据库 | ### 数据库层 | 功能 | 说明 | |------|------| | 连接池 | 固定大小数组连接池,线程安全获取/释放,自动验证连接有效性 | | 事务管理 | ThreadLocal 事务管理,支持声明式(`transaction=true`)和编程式事务 | | 嵌套事务 | 最外层事务生效,内层事务自动加入 | | 事务回调 | `pushCommitBackCall()` 注册事务提交后执行的回调 | | SQL 日志 | Debug 模式下打印完整 SQL 语句、参数值与执行耗时 | ### 缓存系统 | 类型 | 接口 | 说明 | |------|------|------| | 单键缓存 | `FlushCache` | 一个 Key 对应一个对象,自动加载 | | 双键缓存 | `FlushCache2` | 两个 Key 联合定位,适用于复合条件 | | 列表缓存 | `FlushCacheList` | 一个 Key 对应一个列表 | | 通用缓存 | `CacheHost` | Key-Value 缓存,默认 TTL 30 分钟,自动过期清理 | 所有缓存内置容量上限保护,超过阈值自动淘汰。 ### 任务调度 | 注解 | 说明 | |------|------| | `@TaskStartRunMeta(init=true, interval=60)` | 启动时立即执行,之后每 N 秒执行一次 | | `@TaskTimerRunMeta(hour={9}, minute={0,30})` | Cron 风格定时,支持年/月/日/时/分/秒/周匹配 | 任务在线程池中执行,防止线程数爆炸;同一任务串行执行,防止并发重叠。 ### 安全机制 | 功能 | 配置方式 | 说明 | |------|----------|------| | URL 白名单 | `urlmarker.xml` `` | 仅允许配置的路径访问 | | URL 重定向 | `` | 访问指定路径时自动重定向 | | Referer 校验 | `` | 验证请求来源域名 | | 授权头匹配 | `` | 支持 Authorization Header 前缀匹配 | | 浏览器缓存 | `` | 配置 Cache-Control 响应头 | | 自定义 Header | `
` | 添加自定义安全响应头 | | 敏感字段过滤 | `mconfig.properties` `secret_field` | 查询结果自动移除指定字段 | | 扩展名拦截 | 内置 | 自动拦截 `.php`、`.jsp`、`.do`、`.action` 等请求 | ## 项目架构 ### 整体分层 ``` m-server ├── m.server # Web 服务器层 │ ├── TcpServer # TCP 服务器(线程池 + SSL) │ ├── ServerHandler # Socket 处理抽象类 │ └── web/ │ ├── WebHandler # HTTP 请求处理器 │ ├── Request # HTTP 请求解析 │ ├── Response # HTTP 响应构建 │ ├── ActionRedirect # Action 执行器(事务 + 反射) │ ├── AuthInfoUtil # 会话管理(ThreadLocal) │ └── req/res # 请求/响应相关类型定义 │ ├── m.common # 通用业务框架层 │ ├── action/ │ │ ├── Action # 控制器基类 │ │ ├── ActionRequest # 类级路由注解 │ │ ├── RequestMethod # 方法级路由注解 │ │ └── Param # 参数绑定注解 │ ├── model/ │ │ ├── Model # 模型基类(oid 主键) │ │ ├── TableMeta # 表注解 │ │ ├── FieldMeta # 字段注解 │ │ ├── LinkTableMeta # 外键关联注解 │ │ ├── config/ModelConfig # 模型元数据注册中心 │ │ └── util/ # ORM 工具(查询/更新/条件/分页) │ └── service/ │ └── Service # 业务逻辑基类(CRUD 封装) │ └── m.system # 系统基础设施层 ├── db/ # 数据库(连接池、SQL 执行、事务管理) ├── cache/ # 缓存(内存缓存、分布式节点分区) ├── task/ # 任务调度(线程池、间隔任务、Cron 定时任务) ├── url/UrlMarker # XML 路由与访问控制 ├── listener/ # 系统初始化与组件扫描 └── util/ # 工具类(字符串、日期、反射、ID 生成等) ``` ### 请求处理流程 ``` TcpServer.start(port) │ Socket accept (线程池) │ WebHandler │ ┌─────────┴─────────┐ │ Request 解析 │ HTTP 方法、URI、Header、Body └─────────┬─────────┘ │ ┌─────────┴─────────┐ │ AuthInfoUtil.init │ ThreadLocal 绑定 Session └─────────┬─────────┘ │ ┌─────────┴─────────┐ │ UrlMarker 过滤 │ 重定向、白名单、Referer、授权 └─────────┬─────────┘ │ ┌─────────┴─────────┐ │ ActionUtil 路由 │ URL → Action 类 + 方法 └─────────┬─────────┘ │ ┌─────────┴─────────┐ │ ActionRedirect │ 反射调用,可选事务包装 │ ├─ beforeExecute │ │ ├─ Action.method │ ← 业务逻辑在这里 │ ├─ afterExecute │ │ └─ exceptionExe │ └─────────┬─────────┘ │ ┌─────────┴─────────┐ │ Response 输出 │ JSON / 文件 / 重定向 └─────────┬─────────┘ │ 资源清理关闭 ``` ### 核心模块详解 #### 1. Web 服务器(m.server) - **TcpServer**:基于 `ServerSocket` 的 TCP 服务器,使用固定大小线程池处理并发请求 - **SSL 支持**:配置 JKS 证书后自动启用 HTTPS - **WebHandler**:继承 `ServerHandler`,负责完整的 HTTP 请求生命周期 #### 2. Action 控制器(m.common.action) 通过注解将 URL 映射到 Java 方法: - `@ActionRequest(name="路径")` — 标注 Action 类,定义 URL 前缀 - `@RequestMethod(name="路径")` — 标注方法,定义完整 URL - `@Param("参数名")` — 标注方法参数,从请求中取值 Action 基类提供三个生命周期钩子: - `beforeExecute()` — 方法执行前 - `afterExecute()` — 方法执行后 - `exceptionExecute()` — 方法异常时 #### 3. ORM 模型层(m.common.model) 基于注解的元数据驱动 ORM: | 注解 | 作用 | 示例 | |------|------|------| | `@TableMeta` | 定义表名、数据源 | `@TableMeta(name="t_user", db="default")` | | `@FieldMeta` | 定义列名、类型、长度 | `@FieldMeta(name="username", type=FieldType.STRING, length=50)` | | `@LinkTableMeta` | 定义外键关联 | `@LinkTableMeta(name="role_id")` | | `@KeyFieldMeta` | 定义主键 | `@KeyFieldMeta(name="oid")` | 支持操作: - **查询**:主键查询、条件查询、分页查询、联表查询、自定义 SQL - **更新**:新增、修改、保存(自动判断 insert/update)、批量操作、删除 - **自动建表**:启动时根据 Model 注解自动创建/更新表结构 #### 4. 数据库层(m.system.db) - **DBConnection**:固定大小连接池,线程安全获取/释放连接 - **DBManager**:SQL 执行器,支持增删改查和批量操作 - **TransactionManager**:ThreadLocal 事务管理,支持声明式事务和嵌套事务 - **多数据源**:每个 Model 可指定不同的数据库 #### 5. 缓存系统(m.system.cache) 提供三种缓存接口: | 类型 | 接口 | 适用场景 | |------|------|----------| | 单键缓存 | `FlushCache` | 一个 Key 对应一个对象 | | 双键缓存 | `FlushCache2` | 两个 Key 联合定位一个对象 | | 列表缓存 | `FlushCacheList` | 一个 Key 对应一个列表 | 默认 TTL 30 分钟,内置容量上限保护,支持分布式节点分区存储。 #### 6. 任务调度(m.system.task) 两种任务注解: - **`@TaskStartRunMeta`** — 间隔执行任务 ```java @TaskStartRunMeta(init=true, interval=60) // 启动时立即执行,之后每60秒执行一次 public void refreshCache() { ... } ``` - **`@TaskTimerRunMeta`** — Cron 定时任务 ```java @TaskTimerRunMeta(hour={9}, minute={0,30}) // 每天 9:00 和 9:30 执行 public void dailyReport() { ... } ``` #### 7. 路由与安全(m.system.url.UrlMarker) 通过 `urlmarker.xml` 配置: - **redirect** — URL 重定向 - **enable** — 访问白名单 - **cache** — 浏览器缓存策略 - **referer** — 来路域名校验 - **authorization** — 授权头前缀匹配 - **header** — 自定义响应头 ## 快速开始 ### 环境与配置 **1. 前置条件** - JDK 1.8+ - MySQL 8.0+ - Maven 3.x **2. 创建数据库** ```sql CREATE SCHEMA mserver CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci; ``` **3. 配置数据库**(`src/main/resources/dbconfig.properties`) ```properties db_driver=com.mysql.cj.jdbc.Driver db_url=jdbc:mysql://127.0.0.1:3306/mserver?useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true&rewriteBatchedStatements=true db_username=root db_password=your_password db_init_connect=SET NAMES utf8mb4 COLLATE utf8mb4_general_ci db_max_connect=100 db_query_timeout=600 # 节点编号 (0-35),多节点部署时各节点设置不同值 node_index=1 # 调试模式,打印 SQL 日志 debug=true # 输出日志到文件 out_log=false # JKS 证书路径(不配置则启动 HTTP,配置则启动 HTTPS) jks_cert= jks_pass= ``` **4. 配置包扫描路径**(`src/main/resources/config/mconfig.properties`) ```properties # Model 所在包,多个用逗号分隔 model_pack=com.example.model # Action 所在包,多个用逗号分隔 action_pack=com.example.action # Task 所在包,多个用逗号分隔 task_pack=com.example.task # 敏感字段(查询时自动过滤) secret_field=password,secret ``` **5. 启动服务** ```bash # Maven 打包 mvn clean package # 运行(默认端口 9999) java -jar m-server-1.0-SNAPSHOT.jar # 指定端口 java -jar m-server-1.0-SNAPSHOT.jar 8080 ``` 启动成功后输出:`服务启动成功,端口:9999` ### 定义 Model ```java @TableMeta(name="t_user") public class UserModel extends Model { @FieldMeta(name="username", type=FieldType.STRING, length=50) private String username; @FieldMeta(name="age", type=FieldType.INT) private Integer age; @FieldMeta(name="email", type=FieldType.STRING, length=100) private String email; @LinkTableMeta(name="dept_id") private DeptModel dept; // getter/setter ... } ``` 启动时自动在数据库中创建 `t_user` 表(如果不存在)。 ### 定义 Action ```java @ActionRequest(name="user") public class UserAction extends Action { @RequestMethod(name="list") public JSONMessage list(@Param("page") int page, @Param("size") int size) throws Exception { Service service = getService(); // 使用 ModelQueryList 进行分页查询 QueryPage queryPage = new QueryPage(page, size); // ... 查询逻辑 return new JSONMessage().push("list", resultList).push("total", total); } @RequestMethod(name="save", transaction=true) public JSONMessage save() throws Exception { Service service = getService(); UserModel user = getRequest().getRequestJson().toJavaObject(UserModel.class); service.saveModel(user); return new JSONMessage().push("oid", user.getOid()); } @RequestMethod(name="delete", transaction=true) public JSONMessage delete(@Param("oid") String oid) throws Exception { Service service = getService(); UserModel user = new UserModel(); user.setOid(oid); service.deleteModel(user); return new JSONMessage(); } } ``` 以上 Action 对应的访问 URL 为: - `POST /user/list` — 用户列表 - `POST /user/save` — 保存用户 - `POST /user/delete` — 删除用户 ### 定义 Service ```java public class UserService extends Service { public UserModel findByUsername(String username) throws Exception { return getModel(UserModel.class, new String[]{"oid", "username", "email"}, QueryCondition.eq("username", username) ); } public List listByDept(String deptOid) throws Exception { // 使用 ModelQueryList 构建复杂查询 // ... } } ``` ### 定义定时任务 ```java public class DataTask { @TaskStartRunMeta(init=true, interval=300) public void refreshCache() { // 启动时立即执行,之后每 300 秒执行一次 } @TaskTimerRunMeta(hour={2}, minute={0}) public void dailyCleanup() { // 每天凌晨 2:00 执行 } } ``` ### 配置路由与访问控制 编辑 `src/main/resources/config/urlmarker.xml`: ```xml
``` ### 使用缓存 ```java // 实现 FlushCache 接口 public class UserCache implements FlushCache { @Override public UserModel getCacheModel(String key) { // 从数据库加载 return ... } } // 使用 UserModel user = CacheUtil.get(UserCache.class, "user_001"); ``` ## 引用框架 > 示例项目:[m.member 会员管理系统H5版](https://gitee.com/huhuanan/m.member) > > 管理端开发平台:[m-server.manage 轻量级权限管理开发框架(含工作流)](https://gitee.com/huhuanan/m-server.manage) ### 方式一:Maven 本地仓库引用(推荐) 配置简单,框架更新时重新 `mvn install` 即可同步。 **1. 安装框架到本地仓库** ```bash git clone https://gitee.com/huhuanan/m-server.git cd m-server mvn install ``` **2. 在新项目 pom.xml 中添加依赖** ```xml m m-server 1.0-SNAPSHOT ``` **3. 拷贝配置文件** 将框架 `src/main/resources/` 下的配置文件拷贝到新项目对应目录,根据实际情况修改数据库连接等配置: - `dbconfig.properties` — 数据库连接配置 - `config/mconfig.properties` — 包扫描路径配置 - `config/urlmarker.xml` — 路由与访问控制配置 **4. 添加启动入口** 拷贝 `Start.java` 到新项目的 Java 源码目录,作为启动类。 ### 方式二:本地 JAR 引用 框架更新时将新打包的 JAR 替换到 `lib` 目录即可,无需重新 install。 **1. 打包并拷贝 JAR** ```bash cd m-server mvn clean package cp target/m-server-1.0-SNAPSHOT.jar your-project/lib/ ``` **2. 在新项目 pom.xml 中添加依赖和打包配置** ```xml m m-server 1.0-SNAPSHOT system ${pom.basedir}/lib/m-server-1.0-SNAPSHOT.jar mysql mysql-connector-java 8.0.33 com.alibaba.fastjson2 fastjson2 2.0.61 org.apache.maven.plugins maven-jar-plugin 2.6 true lib/ Start lib/m-server-1.0-SNAPSHOT.jar ``` **3. 拷贝配置文件和启动入口**(同方式一的步骤 3-4) ### 方式三:源码集成 直接基于框架源码开发,可自由修改框架内部代码。适合需要深度定制框架的场景。 **方式 A — 克隆后直接开发** ```bash git clone https://gitee.com/huhuanan/m-server.git your-project cd your-project # 修改目录名和 pom.xml 中的 groupId/artifactId ``` **方式 B — 拷贝源码到已有项目** 将框架 `src/main/java/` 和 `src/main/resources/` 下的全部文件拷贝到新项目对应目录,然后在 `pom.xml` 中添加 MySQL 和 FastJSON2 依赖即可。 ## 框架优势 | 优势 | 说明 | |------|------| | **极简依赖** | 仅 MySQL 驱动 + FastJSON2,无 Spring 体系庞大依赖链,JAR 包体积极小 | | **启动快速** | 无 IoC 容器初始化和组件扫描开销,毫秒级启动 | | **资源占用低** | 无反射代理、无字节码增强,内存占用远低于 Spring Boot | | **全栈自研** | Web 服务器、ORM、缓存、任务调度一体化,无整合适配问题 | | **注解驱动** | Model、Action、Task 均通过注解声明,约定优于配置 | | **自动建表** | 根据 Model 注解自动创建和更新数据库表结构,减少手动维护 | | **声明式事务** | `@RequestMethod(transaction=true)` 一行注解开启事务,也可编程式管理 | | **灵活查询** | 支持主键查询、条件构造器、分页、联表、自定义 SQL 等多种查询方式 | | **多数据源** | 每个 Model 可指定不同的数据库,天然支持分库 | | **分布式友好** | 节点索引分区(0-35)、分布式 ID 生成器,可横向扩展 | | **安全可控** | URL 白名单、Referer 校验、授权头匹配、敏感字段过滤等多层安全机制 | | **SSL 内置** | 配置 JKS 证书即启用 HTTPS,无需外部代理 | | **易于部署** | 单 JAR + lib 目录,`java -jar` 即可运行,不依赖容器 | --- > 适用场景:中小型后端服务、API 服务、微服务轻量节点、对启动速度和资源占用有要求的场景。