{"id":51849218,"url":"https://github.com/dingkui/dlz-spring","last_synced_at":"2026-07-23T17:01:31.670Z","repository":{"id":354125744,"uuid":"1222250072","full_name":"dingkui/dlz-spring","owner":"dingkui","description":null,"archived":false,"fork":false,"pushed_at":"2026-05-17T06:37:56.000Z","size":545,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-17T08:40:32.075Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dingkui.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-27T07:22:37.000Z","updated_at":"2026-05-17T06:37:47.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/dingkui/dlz-spring","commit_stats":null,"previous_names":["dingkui/dlz.spring","dingkui/dlz-spring"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/dingkui/dlz-spring","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dingkui%2Fdlz-spring","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dingkui%2Fdlz-spring/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dingkui%2Fdlz-spring/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dingkui%2Fdlz-spring/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dingkui","download_url":"https://codeload.github.com/dingkui/dlz-spring/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dingkui%2Fdlz-spring/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35809505,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-07-20T02:08:10.276Z","status":"online","status_checked_at":"2026-07-23T02:00:06.683Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-07-23T17:01:30.523Z","updated_at":"2026-07-23T17:01:31.645Z","avatar_url":"https://github.com/dingkui.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# DLZ-Spring - Dlz-kit Spring 增强工具集\n\n\u003cdiv\u003e\n\n[![Version](https://img.shields.io/badge/Version-6.6.1--SNAPSHOT-orange.svg)](https://github.com/dingkui/dlz-spring)\n[![JDK](https://img.shields.io/badge/JDK-8+-green.svg)](https://www.oracle.com/java/)\n[![Spring Boot](https://img.shields.io/badge/Spring%20Boot-2.x-brightgreen.svg)](https://spring.io/projects/spring-boot)\n\n**一个让 Spring 开发更简单、更高效的工具集**\n\n**代码量减少 85% | 开发效率提升 5 倍 | 深层穿透 | 自动类型转换**\n\n[快速开始](#快速开始) | [核心功能](#核心功能与亮点) | [文档导航](#文档导航) | [性能对比](#性能对比)\n\n\u003c/div\u003e\n\n---\n\n## 🌟 核心卖点\n\n### ⚡ 代码量减少 85%\n\n```java\n// 传统方式：20+ 行代码\n// DLZ.Spring：3 行代码\nJSONMap response = new JSONMap(HttpEnum.POST.send(url, params));\nString orderId = response.getStr(\"data.order.orderId\");\n```\n\n### 🎯 深层穿透，一步到位\n\n```java\n// 无需层层判空，直接访问深层数据\nString orderId = response.getStr(\"data.order.orderId\");\nString city = response.getStr(\"data.user.profile.address.city\");\n```\n\n### 🔄 自动类型转换\n\n```java\n// \"123\" → Integer 123\n// \"true\" → Boolean true\n// \"99.9\" → Double 99.9\nInteger age = response.getInt(\"age\");\n```\n\n### 🛡️ 空值安全\n\n```java\n// 路径不存在返回 null，不抛 NPE\nString nickname = response.getStr(\"data.user.nickname\");\n```\n\n### 📦 数组访问（支持负索引）\n\n```java\nString firstTag = response.getStr(\"tags[0]\");   // 第一个\nString lastTag = response.getStr(\"tags[-1]\");   // 最后一个\n```\n\n---\n\n## 📖 项目简介\n\nDLZ.Spring 是一个基于 Spring Boot 的增强工具集，提供 HTTP 客户端、Redis 操作、缓存管理、树形结构处理等常用功能，旨在简化 Spring 应用开发，提升开发效率。\n\n### 🎯 为什么选择 DLZ.Spring？\n\n#### 传统方式的痛点\n\n```java\n// ❌ 调用第三方 API，需要 20+ 行代码\nString response = restTemplate.postForObject(url, request, String.class);\nMap\u003cString, Object\u003e map = JSON.parseObject(response);\nInteger code = (Integer) map.get(\"code\");\nif (code == null || code != 0) {\n    throw new Exception(\"请求失败\");\n}\nString orderId = null;\nif (map.containsKey(\"data\")) {\n    Map data = (Map) map.get(\"data\");\n    if (data != null \u0026\u0026 data.containsKey(\"order\")) {\n        Map order = (Map) data.get(\"order\");\n        if (order != null) {\n            orderId = (String) order.get(\"orderId\");\n        }\n    }\n}\n// 层层判空，代码冗长，容易出错\n```\n\n#### DLZ.Spring 的方式\n\n```java\n// ✅ 只需 3 行代码，代码量减少 85%\nJSONMap response = new JSONMap(HttpEnum.POST.send(url, params));\nif (response.getInt(\"code\") != 0) throw new Exception(\"请求失败\");\nString orderId = response.getStr(\"data.order.orderId\");  // 深层穿透，一步到位\n```\n\n### 核心理念\n\n- **极致效率** - 代码量减少 85%，开发效率提升 5 倍\n- **优雅设计** - 深层穿透、自动类型转换、空值安全\n- **功能完善** - HTTP、Redis、缓存、树形结构、加密等常用场景\n- **完美组合** - HttpUtil + JSONMap 黄金组合，一个模式解决 80% 的场景\n\n---\n\n## ✨ 核心功能与亮点\n\n### 1️⃣ HttpUtil + JSONMap 黄金组合（最大卖点）\n\n**代码量减少 85%，开发效率提升 5 倍**\n\n#### 亮点 1：深层穿透，一步到位\n\n```java\n// ❌ 传统方式：层层判空，20+ 行代码\nMap data = (Map) map.get(\"data\");\nif (data != null \u0026\u0026 data.containsKey(\"order\")) {\n    Map order = (Map) data.get(\"order\");\n    if (order != null) {\n        orderId = (String) order.get(\"orderId\");\n    }\n}\n\n// ✅ DLZ.Spring：深层穿透，1 行代码\nString orderId = response.getStr(\"data.order.orderId\");\n```\n\n#### 亮点 2：自动类型转换\n\n```java\n// API 返回的数据类型混乱\n{\n  \"age\": \"25\",        // 字符串\n  \"price\": \"99.9\",    // 字符串\n  \"active\": \"true\",   // 字符串\n  \"count\": 3.0        // 浮点数\n}\n\n// ✅ 自动类型转换，无需手动处理\nInteger age = response.getInt(\"age\");           // \"25\" → 25\nDouble price = response.getDouble(\"price\");     // \"99.9\" → 99.9\nBoolean active = response.getBoolean(\"active\"); // \"true\" → true\nInteger count = response.getInt(\"count\");       // 3.0 → 3\n```\n\n#### 亮点 3：数组访问（支持负索引）\n\n```java\n// 访问数组元素\nString firstTag = response.getStr(\"tags[0]\");   // 第一个\nString lastTag = response.getStr(\"tags[-1]\");   // 最后一个（负索引）\n```\n\n#### 亮点 4：空值安全\n\n```java\n// 路径不存在返回 null，不抛 NPE\nString nickname = response.getStr(\"data.user.nickname\");  // 安全\nString nickname = response.getStr(\"data.user.nickname\", \"匿名\");  // 带默认值\n```\n\n**核心特性**：\n- ⚡ 代码量减少 85%\n- 🎯 深层穿透：`data.order.orderId` 一步到位\n- 🔄 自动类型转换：`\"123\"` → `Integer 123`\n- 🛡️ 空值安全：路径不存在返回 null\n- 📦 数组访问：支持 `arr[0]` 和 `arr[-1]`\n- 🔗 支持 GET/POST/PUT/DELETE 等方法\n- 📄 支持 Form/JSON/Text 多种数据格式\n\n### 2️⃣ Redis 对象自动序列化（开发效率提升）\n\n**无需手动序列化，一行代码搞定对象缓存**\n\n```java\n// ❌ 传统方式：需要手动序列化\nString json = JSON.toJSONString(user);\nredisTemplate.opsForValue().set(\"user:1\", json);\nString cached = redisTemplate.opsForValue().get(\"user:1\");\nUser user = JSON.parseObject(cached, User.class);\n\n// ✅ DLZ.Spring：自动序列化\nUser user = new User(\"张三\", 25);\nRedisUtil.setObj(\"user:1\", user, 3600);\nUser cached = RedisUtil.getObj(\"user:1\", User.class);\n```\n\n**核心特性**：\n- ⚡ 对象自动序列化为 JSON\n- 🔄 取出时自动反序列化\n- 🛡️ 类型安全\n- 🔗 完整的数据结构支持：String、Hash、List、Set\n- 🏊 连接池管理，线程安全\n\n**其他操作**：\n```java\n// 字符串\nRedisUtil.set(\"key\", \"value\", 3600);  // 带过期时间\nString value = RedisUtil.get(\"key\");\n\n// Hash\nRedisUtil.hset(\"user:1\", \"name\", \"张三\");\nString name = RedisUtil.hget(\"user:1\", \"name\");\n\n// List\nRedisUtil.lpush(\"list\", \"value1\", \"value2\");\nList\u003cString\u003e list = RedisUtil.lrange(\"list\", 0, -1);\n\n// Set\nRedisUtil.sadd(\"set\", \"member1\", \"member2\");\nSet\u003cString\u003e members = RedisUtil.smembers(\"set\");\n```\n\n### 3️⃣ 注解式缓存管理（AOP 增强）\n\n**方法结果自动缓存，更新时自动清除**\n\n```java\n@Service\npublic class UserService {\n    \n    // 自动缓存方法结果\n    @CacheAnno(key = \"user:#{userId}\", ttl = 3600)\n    public User getUserById(Long userId) {\n        return userMapper.selectById(userId);\n    }\n    \n    // 更新时自动清除缓存\n    @CacheEvictAnno(key = \"user:#{user.id}\")\n    public void updateUser(User user) {\n        userMapper.updateById(user);\n    }\n}\n```\n\n**核心特性**：\n- ⚡ 注解式缓存，无需手动管理\n- 🔄 自动清除缓存\n- 🎯 灵活的 Key 生成：支持 SpEL 表达式\n- 🏗️ 多级缓存支持：Ehcache、Redis 可选\n- 🔧 可自定义 KeyMaker\n\n### 4️⃣ 树形结构一键转换（算法优化）\n\n**一行代码搞定树形结构，支持任意多级**\n\n```java\n// ❌ 传统方式：需要递归函数，20+ 行代码\npublic List\u003cMenu\u003e buildTree(List\u003cMenu\u003e menuList) {\n    List\u003cMenu\u003e tree = new ArrayList\u003c\u003e();\n    for (Menu menu : menuList) {\n        if (menu.getParentId() == null) {\n            menu.setChildren(getChildren(menu, menuList));\n            tree.add(menu);\n        }\n    }\n    return tree;\n}\nprivate List\u003cMenu\u003e getChildren(Menu parent, List\u003cMenu\u003e menuList) {\n    // 递归查找子节点...\n}\n\n// ✅ DLZ.Spring：一行代码\nList\u003cMenu\u003e tree = TreeUtil.toTree(menuList);\n```\n\n**核心特性**：\n- ⚡ 一行代码转树形\n- 🌲 支持任意多级\n- 🔧 支持 JSONMap（无需定义实体类）\n- 🏗️ 自动创建父节点（可选）\n- 🎯 Lambda 支持：灵活指定字段映射\n\n**使用示例**：\n```java\n// 方式 1：实体类实现 ITree 接口\nList\u003cMenu\u003e tree = TreeUtil.toTree(menuList);\n\n// 方式 2：使用 JSONMap\nList\u003cJSONMap\u003e tree = TreeUtil.toTree(items, \"id\", \"parentId\");\n\n// 方式 3：Lambda 指定字段\nList\u003cDept\u003e tree = TreeUtil.toTree(\n    deptList,\n    Dept::getId,\n    Dept::getParentId,\n    Dept::getChildren,\n    Dept::setChildren\n);\n```\n\n### 5️⃣ 接口代理扫描（RPC 利器）\n\n**动态接口代理，无需实现类**\n\n```java\n// 定义接口\n@ApiProxy\npublic interface UserApi {\n    @ApiMethod(\"/users/{id}\")\n    User getUserById(@PathVariable Long id);\n    \n    @ApiMethod(\"/users\")\n    List\u003cUser\u003e listUsers(@RequestParam Map\u003cString, Object\u003e params);\n}\n\n// 自动生成代理实现，直接调用\nUser user = userApi.getUserById(1L);\n```\n\n**核心特性**：\n- ⚡ 动态接口代理，无需实现类\n- 🔄 参数自动映射为 JSONMap\n- 🎯 适用场景：RPC 调用、API 网关、Feign 替代\n- 🔧 可自定义代理处理器\n\n### 6️⃣ SpringHolder 静态工具\n\n**便捷的 Spring 上下文操作**\n\n```java\n// 获取 Bean（无需注入）\nUserService userService = SpringHolder.getBean(UserService.class);\n\n// 获取配置\nString value = SpringHolder.getProperty(\"app.name\");\n\n// 发布事件\nSpringHolder.publishEvent(new UserCreatedEvent(user));\n```\n\n### 7️⃣ 加密工具集\n\n**常用加密算法开箱即用**\n\n```java\n// MD5\nString md5 = Md5Util.md5(\"password\");\n\n// Base64\nString encoded = Base64.encode(\"data\");\n\n// RSA 签名\nString sign = RSASignature.sign(content, privateKey);\nboolean valid = RSASignature.doCheck(content, sign, publicKey);\n```\n\n### 8️⃣ 智能类型转换\n\n**多种转换策略，自动选择最优方案**\n\n```java\n// Bean 转换\nUserVO userVO = ConvertUtil.convert(user, UserVO.class);\n\n// 带回调\nUserVO userVO = ConvertUtil.convert(user, UserVO.class, vo -\u003e {\n    vo.setRoleName(\"管理员\");\n});\n\n// List 批量转换\nList\u003cUserVO\u003e voList = ConvertUtil.convertList(userList, UserVO.class);\n```\n\n### 9️⃣ 智能响应处理器\n\n**自动处理 HTTP 状态码和异常**\n\n```java\n// 自动处理状态码\n// 200/201/202 → 成功返回\n// 404 → 抛出 HttpException(\"地址无效\")\n// 401/403 → 抛出 HttpException(\"无访问权限\")\n// 其他 → 抛出对应异常\n\n// 支持泛型，自动解析\nHttpRequestParam\u003cUser\u003e param = new HttpRequestParam\u003c\u003e(url, User.class);\nUser user = HttpEnum.GET.send(param);  // 直接返回 User 对象\n```\n\n---\n\n## 🚀 快速开始\n\n### 环境要求\n\n- JDK 8+\n- Spring Boot 2.x\n- Maven 3.5+\n\n### 1. 添加依赖\n\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003etop.dlzio\u003c/groupId\u003e\n    \u003cartifactId\u003edlz-spring\u003c/artifactId\u003e\n    \u003cversion\u003e6.6.4\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n### 2. 配置 Redis（可选）\n\n```yaml\nspring:\n  redis:\n    host: localhost\n    port: 6379\n    password: \n    database: 0\n    timeout: 3000\n    jedis:\n      pool:\n        max-active: 8\n        max-wait: -1\n        max-idle: 8\n        min-idle: 0\n```\n\n### 3. 使用示例\n\n#### HTTP 请求\n\n```java\n// GET 请求\nString result = HttpEnum.GET.send(\"https://api.example.com/users\");\n\n// POST 请求（JSON 格式）\nJSONMap data = new JSONMap(\"name\", \"张三\", \"age\", 25);\nHttpRequestParam param = HttpRequestParam.createJsonReq(url, data);\nparam.addHeader(\"Authorization\", \"Bearer token\");\nString response = HttpEnum.POST.send(param);\n\n// 响应解析（使用 JSONMap）\nJSONMap result = new JSONMap(response);\nString orderId = result.getStr(\"data.order.orderId\");\nInteger amount = result.getInt(\"data.order.amount\");\n```\n\n#### Redis 操作\n\n```java\n// 字符串\nRedisUtil.set(\"key\", \"value\", 3600);  // 设置过期时间\nString value = RedisUtil.get(\"key\");\n\n// 对象\nUser user = new User(\"张三\", 25);\nRedisUtil.setObj(\"user:1\", user);\nUser cached = RedisUtil.getObj(\"user:1\", User.class);\n\n// Hash\nRedisUtil.hset(\"user:1\", \"name\", \"张三\");\nString name = RedisUtil.hget(\"user:1\", \"name\");\n```\n\n#### 树形结构\n\n```java\n// 实体类实现 ITree 接口\npublic class Menu implements ITree\u003cLong, Menu\u003e {\n    private Long id;\n    private Long parentId;\n    private List\u003cMenu\u003e children;\n    \n    // getter/setter...\n}\n\n// 转换为树形结构\nList\u003cMenu\u003e menuList = menuService.list();\nList\u003cMenu\u003e tree = TreeUtil.toTree(menuList);\n```\n\n---\n\n## 📚 文档导航\n\n### 核心文档\n\n| 文档 | 说明 |\n|------|------|\n| [AI 速读指南](docs/AI-速读指南.md) | 3 分钟快速上手 |\n| [HttpUtil 快速入门](docs/HttpUtil快速入门.md) | HTTP 客户端快速入门 |\n| [HttpUtil 使用手册](docs/HttpUtil使用手册.md) | HTTP 客户端完整手册 |\n| [完整功能文档](docs/DLZ-Spring完整功能文档.md) | 所有功能详细说明 |\n\n## 💡 核心优势\n\n### 1. 极致的开发效率\n\n**代码量对比**：\n\n| 功能 | 传统方式 | DLZ.Spring | 减少 |\n|------|---------|-----------|------|\n| HTTP 请求 + 响应解析 | 20+ 行 | 3 行 | 85% |\n| Redis 对象缓存 | 4 行 | 1 行 | 75% |\n| 树形结构转换 | 20+ 行 | 1 行 | 95% |\n| 注解式缓存 | 手动管理 | 自动管理 | - |\n\n**开发效率提升**：\n- ⚡ HTTP 请求：从 10 分钟缩短到 2 分钟\n- ⚡ Redis 操作：无需手动序列化\n- ⚡ 树形结构：无需编写递归函数\n- ⚡ 缓存管理：注解自动管理\n\n### 2. 优雅的 API 设计\n\n**深层穿透**：\n```java\n// 一步到位，无需层层判空\nString orderId = response.getStr(\"data.order.orderId\");\nString city = response.getStr(\"data.user.profile.address.city\");\n```\n\n**链式调用**：\n```java\nHttpRequestParam param = HttpRequestParam.createJsonReq(url, data)\n    .addHeader(\"Authorization\", \"Bearer token\")\n    .setRequestConfig(config)\n    .setShowLog(true);\n```\n\n**Lambda 支持**：\n```java\nList\u003cMenu\u003e tree = TreeUtil.toTree(\n    menuList,\n    Menu::getId,\n    Menu::getParentId\n);\n```\n\n### 3. 强大的功能特性\n\n**自动类型转换**：\n- `\"123\"` → `Integer 123`\n- `\"true\"` → `Boolean true`\n- `\"99.9\"` → `Double 99.9`\n\n**空值安全**：\n- 路径不存在返回 null，不抛 NPE\n- 支持默认值：`response.getStr(\"key\", \"默认值\")`\n\n**数组访问**：\n- 正索引：`arr[0]`、`arr[1]`\n- 负索引：`arr[-1]`（倒数第一个）\n\n**智能异常处理**：\n- 自动处理 HTTP 状态码\n- 统一异常体系\n- 详细的错误信息\n\n### 4. 完善的文档体系\n\n- 📖 [AI 速读指南](docs/AI-速读指南.md) - 3 分钟快速上手\n- 📖 [完整功能文档](docs/DLZ-Spring完整功能文档.md) - 深入学习所有功能\n- 📖 [核心特性与热点功能](docs/核心特性与热点功能.md) - 理解核心优势\n- 📖 [HttpUtil 快速入门](docs/HttpUtil快速入门.md) - HTTP 客户端专项\n- 📖 [HttpUtil 使用手册](docs/HttpUtil使用手册.md) - 完整的 API 参考\n\n---\n\n## 🎯 典型应用场景\n\n### 场景 1：调用微信支付 API\n\n```java\npublic class WechatPayClient {\n    private static final String BASE_URL = \"https://api.mch.weixin.qq.com\";\n    \n    public String unifiedOrder(WechatPayRequest request) {\n        // 1. 构造请求\n        String url = BASE_URL + \"/pay/unifiedorder\";\n        HttpRequestParam param = HttpRequestParam.createJsonReq(url, request);\n        param.addHeader(\"Authorization\", \"Bearer \" + getToken());\n        \n        // 2. 发送请求\n        String responseStr = HttpEnum.POST.send(param);\n        \n        // 3. 解析响应（使用 JSONMap）\n        JSONMap response = new JSONMap(responseStr);\n        \n        // 4. 快速取值\n        if (!\"SUCCESS\".equals(response.getStr(\"return_code\"))) {\n            throw new BussinessException(response.getStr(\"return_msg\"));\n        }\n        \n        return response.getStr(\"prepay_id\");\n    }\n}\n```\n\n### 场景 2：用户信息缓存\n\n```java\n@Service\npublic class UserService {\n    \n    public User getUserById(Long userId) {\n        String key = \"user:\" + userId;\n        \n        // 1. 先查缓存\n        User user = RedisUtil.getObj(key, User.class);\n        if (user != null) {\n            return user;\n        }\n        \n        // 2. 缓存不存在，查询数据库\n        user = userMapper.selectById(userId);\n        if (user == null) {\n            return null;\n        }\n        \n        // 3. 写入缓存（1小时过期）\n        RedisUtil.setObj(key, user, 3600);\n        \n        return user;\n    }\n}\n```\n\n### 场景 3：菜单树构建\n\n```java\n@Service\npublic class MenuService {\n    \n    public List\u003cMenu\u003e getMenuTree() {\n        // 1. 查询所有菜单\n        List\u003cMenu\u003e menuList = menuMapper.selectList();\n        \n        // 2. 转换为树形结构（一行代码）\n        return TreeUtil.toTree(menuList);\n    }\n}\n```\n\n---\n\n## 🏗️ 技术架构\n\n### 技术栈\n\n| 技术 | 版本    | 说明 |\n|------|-------|------|\n| Spring Boot | 2.x   | 核心框架 |\n| Apache HttpClient | -     | HTTP 客户端 |\n| Jedis | -     | Redis 客户端 |\n| Ehcache | -     | 本地缓存 |\n| DLZ.Comm | 6.6.2 | 基础工具库（JSONMap/JSONList） |\n\n### 模块结构\n\n```\ndlz.spring/\n├── comm/                      # 通用模块\n│   ├── consts/               # 常量定义\n│   ├── exception/            # 异常体系\n│   ├── inf/                  # 接口定义\n│   └── util/                 # 工具类\n│       ├── config/           # 配置工具\n│       ├── encry/            # 加密工具\n│       ├── system/           # 系统工具\n│       ├── tree/             # 树形结构\n│       └── web/              # HTTP 工具\n│\n└── spring/                    # Spring 模块\n    ├── cache/                # 缓存管理\n    │   ├── aspect/           # 缓存切面\n    │   └── service/          # 缓存服务\n    ├── config/               # 配置类\n    ├── holder/               # 上下文工具\n    │   ├── SpringHolder      # Spring 上下文\n    │   └── TokenHolder       # Token 管理\n    ├── redis/                # Redis 工具\n    │   ├── excutor/          # Redis 执行器\n    │   ├── queue/            # Redis 队列\n    │   ├── service/          # Redis 服务\n    │   └── util/             # Redis 工具\n    └── scan/                 # 接口扫描\n        ├── iproxy/           # 接口代理\n        └── scaner/           # 扫描器\n```\n\n---\n\n## 🎯 适用场景\n\n**强烈推荐使用**：\n- ✅ 调用第三方 API（微信、支付宝、短信等）\n- ✅ Redis 缓存操作\n- ✅ 树形菜单/组织架构处理\n- ✅ 数据加密解密\n- ✅ Spring Bean 动态获取\n\n**典型应用**：\n- 微服务间 HTTP 调用\n- 支付回调处理\n- 权限菜单树构建\n- 用户 Token 管理\n- 接口签名验证\n\n---\n\n## 📊 性能对比\n\n### HttpUtil + JSONMap vs 传统方式\n\n| 指标 | 传统方式 | DLZ.Spring | 提升 |\n|------|---------|-----------|------|\n| 代码行数 | 20+ 行 | 3 行 | 减少 85% |\n| 开发时间 | 10 分钟 | 2 分钟 | 提升 5 倍 |\n| 可读性 | ⭐⭐ | ⭐⭐⭐⭐⭐ | 提升 150% |\n| 维护成本 | 高 | 低 | 降低 70% |\n| 空值安全 | ❌ 需手动判空 | ✅ 自动处理 | - |\n| 类型转换 | ❌ 需手动转换 | ✅ 自动转换 | - |\n\n### Redis 操作 vs 传统方式\n\n| 指标 | 传统方式 | DLZ.Spring | 提升 |\n|------|---------|-----------|------|\n| 代码行数 | 4 行 | 1 行 | 减少 75% |\n| 序列化 | 手动 | 自动 | - |\n| 类型安全 | ❌ | ✅ | - |\n| 连接池管理 | 需配置 | 自动管理 | - |\n\n### 树形结构 vs 传统方式\n\n| 指标 | 传统方式 | DLZ.Spring | 提升 |\n|------|---------|-----------|------|\n| 代码行数 | 20+ 行递归 | 1 行 | 减少 95% |\n| 开发时间 | 30 分钟 | 1 分钟 | 提升 30 倍 |\n| 算法复杂度 | 需自己实现 | 已优化 | - |\n| 支持多级 | 需测试 | 自动支持 | - |\n\n---\n\n## 🔧 配置说明\n\n### application.yml\n\n```yaml\n# DLZ 框架配置\ndlz:\n  fw:\n    # 缓存配置\n    cache:\n      type: redis  # 缓存类型：redis/ehcache\n      ttl: 3600    # 默认过期时间（秒）\n    \n    # Redis 配置\n    redis:\n      key-prefix: \"dlz:\"  # Key 前缀\n\n# Spring Redis 配置\nspring:\n  redis:\n    host: localhost\n    port: 6379\n    password: \n    database: 0\n    timeout: 3000\n    jedis:\n      pool:\n        max-active: 8\n        max-wait: -1\n        max-idle: 8\n        min-idle: 0\n```\n\n---\n\n## 🤝 常见问题\n\n### Q1: HttpUtil 和 RestTemplate 有什么区别？\n\n**相同点**：\n- 都是 HTTP 客户端工具\n- 都支持多种 HTTP 方法\n\n**不同点**：\n- **HttpUtil 更简洁**：API 设计更直观\n- **配合 JSONMap**：响应解析更方便（深层穿透）\n- **代码量更少**：减少 75% 的代码\n\n### Q2: 为什么推荐 HttpUtil + JSONMap？\n\n**核心优势**：\n- **深层穿透**：`response.getStr(\"data.order.orderId\")` 一步到位\n- **自动类型转换**：`\"123\"` 自动转 `Integer 123`\n- **空值安全**：路径不存在返回 null，不抛异常\n- **代码简洁**：20 行代码缩减为 3 行\n\n### Q3: Redis 工具类线程安全吗？\n\n**完全线程安全**：\n- 基于 Jedis 连接池\n- 每次操作从池中获取连接\n- 操作完成后自动归还连接\n\n### Q4: 树形结构工具支持哪些场景？\n\n**支持场景**：\n- 菜单树\n- 组织架构树\n- 分类树\n- 评论树\n- 任意父子关系数据\n\n### Q5: 如何自定义 HTTP 请求超时？\n\n```java\nRequestConfig config = RequestConfig.custom()\n    .setSocketTimeout(10000)      // 读取超时 10秒\n    .setConnectTimeout(5000)      // 连接超时 5秒\n    .build();\n\nHttpRequestParam param = HttpRequestParam.createJsonReq(url, data);\nparam.setRequestConfig(config);\nString result = HttpEnum.POST.send(param);\n```\n\n---\n\n## 🌟 最佳实践\n\n### 1. 统一封装 HTTP 客户端\n\n```java\npublic class ApiClient {\n    private static final String BASE_URL = \"https://api.example.com\";\n    \n    public static JSONMap post(String path, Object data) {\n        HttpRequestParam param = HttpRequestParam.createJsonReq(BASE_URL + path, data);\n        param.addHeader(\"Authorization\", \"Bearer \" + getToken());\n        String response = HttpEnum.POST.send(param);\n        return new JSONMap(response);\n    }\n}\n\n// 使用\nJSONMap result = ApiClient.post(\"/orders\", orderData);\nString orderId = result.getStr(\"data.orderId\");\n```\n\n### 2. Redis 缓存模式\n\n```java\npublic User getUserById(Long userId) {\n    // 先查缓存\n    User user = RedisUtil.getObj(\"user:\" + userId, User.class);\n    if (user == null) {\n        // 缓存不存在，查询数据库\n        user = userMapper.selectById(userId);\n        // 写入缓存\n        RedisUtil.setObj(\"user:\" + userId, user, 3600);\n    }\n    return user;\n}\n```\n\n### 3. 树形菜单构建\n\n```java\n@Service\npublic class MenuService {\n    \n    public List\u003cMenu\u003e getMenuTree() {\n        // 查询所有菜单\n        List\u003cMenu\u003e menuList = menuMapper.selectList();\n        \n        // 转换为树形结构\n        return TreeUtil.toTree(menuList);\n    }\n}\n```\n\n---\n\n## 📝 更新日志\n\n### v6.6.2-SNAPSHOT (当前版本)\n- ✨ 完善 HTTP 工具类\n- ✨ 优化 Redis 操作\n- ✨ 增强树形结构工具\n- 🐛 修复已知问题\n\n---\n\n## 📄 开源协议\n\n本项目采用 MIT 协议开源。\n\n---\n\n## 💬 联系方式\n\n- **问题反馈**: [GitHub Issues](https://github.com/yourusername/dlz.spring/issues)\n\n---\n\n\u003cdiv\u003e\n\n**简洁 | 易用 | 高效**\n\n如果觉得有帮助，请点个 ⭐ Star 支持一下！\n\n[返回顶部](#dlzspring---spring-增强工具集)\n\n\u003c/div\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdingkui%2Fdlz-spring","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdingkui%2Fdlz-spring","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdingkui%2Fdlz-spring/lists"}