DigitalHainan Spring 微服务框架脚手架与集成指南,覆盖 POM、缓存、MyBatis、认证、OSS 等核心模块。

本文档用于指导在目标项目中完成
digitalhainan-ms-common模块集成。执行顺序:
- 先完成「4.1.2 快速集成」的全部步骤(必须)
- 根据业务需求,查阅「功能集成决策索引」选择对应路径,逐项实现
- 遇到配置问题时参考「4.1.3 配置属性参考」
- 出现异常时查阅「4.1.6 常见问题」
代码约定: 所有代码示例均包含完整
import路径和类声明,可直接用于代码生成。
digitalhainan-ms-common 是数字海南框架的 微服务公共组件,为所有微服务提供统一的基础能力:
@AppI18n 注解自动翻译响应字段http_2xx / http_standard 两种响应模式/api/rest/jasypt/encrypt 接口@DynamicScheduled 注解,支持运行时动态修改 Cron 表达式(需 Spring Cloud)TraceContext 工具类Maven 坐标:
<dependency>
<groupId>cn.com.digitalhainan</groupId>
<artifactId>ms-common</artifactId>
</dependency>前置依赖:
| 依赖 | 说明 |
|---|---|
digitalhainan-pom | 父 POM |
digitalhainan-common | 通用基础模块 |
digitalhainan-tools | 工具集模块 |
digitalhainan-log-starter | 日志组件 |
当前版本: 3.1.0-SNAPSHOT
<parent>
<groupId>cn.com.digitalhainan</groupId>
<artifactId>digitalhainan-pom</artifactId>
<version>3.1.0-SNAPSHOT</version>
</parent><dependencies>
<dependency>
<groupId>cn.com.digitalhainan</groupId>
<artifactId>ms-common</artifactId>
</dependency>
</dependencies>digitalhainan:
# MDC 过滤器(默认启用)
enable-mdc-handler: true
component:
# Swagger 文档
swagger:
enable: true
title: "我的微服务 API"
version: "v1.0"
# 异步线程池
task:
task-async-parallel-executor:
core-pool-size: 10
maximum-pool-size: 20
# RestTemplate
rest:
connect-time-out: 5000
read-time-out: 10000
max-total-connect: 200
max-connect-per-route: 50
# Web 响应模式
web:
response:
mode: http_2xx/service/health 返回 {"state":"UP"}/doc.html 可查看 Swagger 文档(如已启用)BaseResponse 格式| 配置键 | 类型 | 默认值 | 说明 |
|---|---|---|---|
digitalhainan.enable-mdc-handler | Boolean | true | 是否启用 MDC 请求追踪过滤器 |
digitalhainan.enable-exception-handler | Boolean | true | 是否启用全局异常处理 |
digitalhainan.base-package | String | — | 基础包路径 |
| 配置键 | 类型 | 默认值 | 说明 |
|---|---|---|---|
digitalhainan.web.response.mode | Enum | http_2xx | 响应模式:http_2xx(所有异常返回 200)/ http_standard(按 HTTP 标准状态码) |
| 配置键 | 类型 | 默认值 | 说明 |
|---|---|---|---|
digitalhainan.component.swagger.enable | Boolean | false | 是否启用 Swagger 文档 |
digitalhainan.component.swagger.title | String | Digitalhainan快速集成Swagger文档 | 文档标题 |
digitalhainan.component.swagger.description | String | — | 文档描述 |
digitalhainan.component.swagger.version | String | v1.0 | 文档版本 |
digitalhainan.component.swagger.base-package | String | — | 扫描包路径 |
digitalhainan.component.swagger.license | String | digtitalhainan | 许可证 |
digitalhainan.component.swagger.contact.name | String | Hl | 联系人 |
digitalhainan.component.swagger.contact.email | String | — | 联系邮箱 |
digitalhainan.component.swagger.authorization.name | String | Authorization | Token Header 名称 |
digitalhainan.component.swagger.authorization.description | String | user token | Token 描述 |
digitalhainan.component.swagger.basic.enable | Boolean | true | 是否启用 Basic Auth |
digitalhainan.component.swagger.basic.username | String | admin | Basic Auth 用户名 |
digitalhainan.component.swagger.basic.password | String | Szhn@123 | Basic Auth 密码 |
| 配置键 | 类型 | 默认值 | 说明 |
|---|---|---|---|
digitalhainan.component.dubbo.validation-expression | String | — | Dubbo 拦截切面表达式(如 execution(* cn.com.digitalhainan..*.*(..))) |
digitalhainan.component.dubbo.exception-cover | Enum | THROW_EXCEPTION | 异常覆盖策略:THROW_EXCEPTION / COVER_RESPONSE |
| 配置键 | 类型 | 默认值 | 说明 |
|---|---|---|---|
digitalhainan.component.task.task-async-parallel-executor.core-pool-size | Integer | 10 | 核心线程数 |
digitalhainan.component.task.task-async-parallel-executor.maximum-pool-size | Integer | 20 | 最大线程数 |
digitalhainan.component.task.task-async-parallel-executor.keep-alive-seconds | Integer | 3600 | 空闲线程存活时间(秒) |
digitalhainan.component.task.task-async-parallel-executor.queue-capacity | Integer | MAX_VALUE | 队列容量 |
digitalhainan.component.task.task-async-parallel-executor.thread-name-prefix | String | digitalhainan-taskExecutor- | 线程名前缀 |
digitalhainan.component.task.task-async-parallel-executor.rejected-execution-strategy | Enum | CALLER_RUNS_POLICY | 拒绝策略:ABORT_POLICY / DISCARD_POLICY / CALLER_RUNS_POLICY / DISCARD_OLDEST_POLICY |
| 配置键 | 类型 | 默认值 | 说明 |
|---|---|---|---|
digitalhainan.component.rest.connect-time-out | Integer | -1 | 连接超时(毫秒),-1 为不限制 |
digitalhainan.component.rest.read-time-out | Integer | -1 | 读取超时(毫秒) |
digitalhainan.component.rest.max-total-connect | Integer | 0 | 最大连接数(>0 启用连接池) |
digitalhainan.component.rest.max-connect-per-route | Integer | 0 | 每路由最大连接数 |
digitalhainan.component.rest.time-to-live | Integer | 120000 | 连接存活时间(毫秒) |
digitalhainan.component.rest.validate-after-inactivity | Integer | 30000 | 不活动后验证间隔(毫秒) |
| 配置键 | 类型 | 默认值 | 说明 |
|---|---|---|---|
digitalhainan.component.request-logging.enable | Boolean | false | 是否启用请求日志 |
digitalhainan.component.request-logging.logging-path-prefix | List | ["/**"] | 日志拦截路径前缀 |
digitalhainan.component.request-logging.ignore-paths | List | [] | 忽略路径 |
digitalhainan.component.request-logging.format-console-log-json | Boolean | true | 控制台日志是否 JSON 格式 |
| 配置键 | 类型 | 默认值 | 说明 |
|---|---|---|---|
digitalhainan.component.exception.report.enable | Boolean | false | 是否启用异常上报 |
digitalhainan.component.exception.report.report-type | Enum | DING_TALK | 上报类型:DING_TALK / ALERT_PLATFORM |
digitalhainan.component.exception.report.ding-talk.url | String | — | 钉钉机器人 Webhook URL |
digitalhainan.component.exception.report.alert-platform.apione-url | String | — | 告警平台 URL |
digitalhainan.component.exception.report.alert-platform.ak | String | — | ApiOne AK |
digitalhainan.component.exception.report.alert-platform.sk | String | — | ApiOne SK |
digitalhainan.component.exception.report.alert-platform.apiname | String | — | ApiOne API 名称 |
digitalhainan.component.exception.report.alert-platform.region | String | — | 区域 |
digitalhainan.component.exception.report.alert-platform.integration-key | String | — | 集成密钥 |
| 配置键 | 类型 | 默认值 | 说明 |
|---|---|---|---|
digitalhainan.health.enable | Boolean | true | 是否启用健康检查端点 /service/health |
| 需求场景 | 参考章节 |
|---|---|
| i18n 国际化异常消息 | 4.1 i18n 国际化 |
| Dubbo 异常拦截与透传 | 4.2 Dubbo 增强 |
| Swagger API 文档 | 4.3 Swagger/Knife4j |
| 全局异常统一处理 | 4.4 全局异常处理 |
| 配置文件 SM4 加密 | 4.5 Jasypt SM4 加密 |
| 异步任务线程池 | 4.6 异步线程池 |
| 动态定时任务 | 4.7 动态定时任务 |
| RestTemplate HTTP 调用 | 4.8 RestTemplate |
| 链路追踪 TraceId | 4.9 链路追踪 |
| HTTP 请求日志 | 4.10 请求日志 |
| 异常上报(钉钉/告警平台) | 4.11 异常上报 |
| Web 响应模式切换 | 4.12 Web 响应模式 |
| 健康检查 | 4.13 健康检查 |
在 src/main/resources/i18n/ 下创建属性文件:
# messages_zh_CN.properties
ERR_RETRY=请稍后重试
ERR_INVALID_PARAMS=无效请求参数
UNAUTHORIZED=无权访问
BUSINESS_ERROR_001=用户 {0} 不存在package com.example.service;
import cn.com.digitalhainan.common.core.annotation.AppI18n;
import cn.com.digitalhainan.common.core.response.BaseResponse;
import org.springframework.stereotype.Service;
/**
* i18n 国际化使用示例
* 在方法上使用 @AppI18n 注解,自动翻译 BaseResponse 中标注了 @AppI18n 的字段
*/
@Service
public class I18nDemoService {
@AppI18n
public BaseResponse<Object, Object> getBusinessData() {
// 抛出业务异常,异常消息会自动通过 i18n 翻译
return BaseResponse.success("操作成功");
}
}package com.example.config;
import cn.com.digitalhainan.common.core.exception.IBusinessExceptionCodeConfiguration;
import cn.com.digitalhainan.ms.common.core.i18n.IBusinessExceptionI18nMessage;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.List;
/**
* 自定义 i18n 消息实现(如从 Redis 读取)
*/
@Configuration
public class CustomI18nConfig {
@Bean
public IBusinessExceptionI18nMessage customI18nMessage() {
return new IBusinessExceptionI18nMessage() {
@Override
public String getMessage(IBusinessExceptionCodeConfiguration exceptionCodeEnum, List<Object> args) {
// 自定义逻辑:从 Redis/数据库获取国际化消息
return exceptionCodeEnum.defaultMsg();
}
@Override
public String getMessage(String code) {
return code;
}
@Override
public String getMessage(String code, List<Object> args) {
return code;
}
};
}
}digitalhainan:
component:
dubbo:
validation-expression: "execution(* cn.com.digitalhainan..dubbo.*.*(..))"
exception-cover: THROW_EXCEPTION # 或 COVER_RESPONSETHROW_EXCEPTION — 使用 ValidationInterceptor,直接抛出异常COVER_RESPONSE — 使用 DubboExceptionInterceptor,将异常转为 BaseResponse 返回Consumer/Provider 异常 Filter 通过 SPI 自动注册,无需额外配置:
META-INF/dubbo/org.apache.dubbo.rpc.cluster.filter.ClusterFilter
META-INF/dubbo/org.apache.dubbo.rpc.Filterdigitalhainan:
component:
swagger:
enable: true
title: "用户服务 API"
description: "用户管理相关接口"
version: "v2.0"
basic:
enable: true
username: admin
password: Szhn@123启动后访问 http://host:port/doc.html,使用 Basic Auth 登录后查看文档。
框架自动接管 /error 路径,所有异常统一转为 BaseResponse 格式:
{
"code": "ERR_RETRY",
"message": "请稍后重试",
"data": null,
"requestId": "trace-id-xxx",
"timestamp": "2024-01-01T00:00:00"
}自定义异常解析器:
package com.example.config;
import cn.com.digitalhainan.common.core.exception.IBusinessExceptionCodeConfiguration;
import cn.com.digitalhainan.common.core.response.BaseResponse;
import cn.com.digitalhainan.ms.common.web.exception.IExceptionInfoResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 自定义异常信息解析器
*/
@Configuration
public class CustomExceptionResolverConfig {
@Bean
public IExceptionInfoResolver customExceptionInfoResolver() {
return new IExceptionInfoResolver() {
@Override
public IBusinessExceptionCodeConfiguration resolverUnrecognizedThrowable(Throwable throwable) {
// 自定义未识别异常的编码映射
return null;
}
@Override
public void tryExtractDebugMsg(BaseResponse baseResponse, Throwable throwable, boolean includeStackTrace) {
// 自定义调试信息提取
}
};
}
}spring:
datasource:
password: ENC(加密后的密文)框架使用 JasyptSm4Encryptor(SM4 CBC 模式)自动解密 ENC(...) 包裹的值。
# 加密明文
curl "http://host:port/api/rest/jasypt/encrypt?message=123456"
# 返回
{
"code": "000000",
"data": "加密后的十六进制字符串",
"state": "UP"
}package com.example.service;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import java.util.concurrent.CompletableFuture;
/**
* 异步任务使用示例
* 框架自动配置线程池 taskAsyncParallelExecutor,并传递 MDC 上下文
*/
@Service
public class AsyncDemoService {
@Async
public CompletableFuture<String> asyncTask() {
// 此方法在线程池中异步执行
// MDC 中的 traceId 会自动传递到子线程
return CompletableFuture.completedFuture("done");
}
}配置线程池参数:
digitalhainan:
component:
task:
task-async-parallel-executor:
core-pool-size: 20
maximum-pool-size: 50
keep-alive-seconds: 600
queue-capacity: 1000
rejected-execution-strategy: CALLER_RUNS_POLICY需要 Spring Cloud 环境(
EnvironmentChangeEvent)
package com.example.job;
import cn.com.digitalhainan.ms.common.core.schedule.DynamicScheduled;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
/**
* 动态定时任务示例
* 使用 @DynamicScheduled 注解标记,支持运行时通过 Nacos 配置中心动态修改 Cron 表达式
*/
@Slf4j
@Component
public class DynamicJobDemo {
@DynamicScheduled("dataSyncJob")
@Scheduled(cron = "${job.data-sync.cron:0 0/5 * * * ?}")
public void execute() {
log.info("执行数据同步任务");
}
}在 Nacos 中修改 job.data-sync.cron 值后,定时任务自动重新调度。
package com.example.service;
import cn.com.digitalhainan.ms.common.core.rest.RestTemplateService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* RestTemplate 使用示例
* 框架自动配置 RestTemplate(连接池 + UTF-8 + Header 透传)
*/
@Service
public class RestDemoService {
@Autowired
private RestTemplateService restTemplateService;
public void callExternalApi() {
// GET 请求
String result = restTemplateService.getForObject(
"http://external-api/users/{id}", String.class, "123");
// POST 请求
// restTemplateService.postForObject(url, requestBody, responseType);
}
}package com.example.util;
import cn.com.digitalhainan.ms.common.core.trace.TraceContext;
/**
* 链路追踪使用示例
*/
public class TraceDemo {
public void demo() {
// 获取当前请求的 TraceId(来自 SkyWalking / MDC)
String traceId = TraceContext.getTraceId();
// 手动设置 TraceId
TraceContext.setTraceId("custom-trace-id");
// 标记当前 Span 为错误
TraceContext.setError("Something went wrong");
// 清除 TraceId
TraceContext.clearTraceId();
}
}digitalhainan:
component:
request-logging:
enable: true
logging-path-prefix:
- "/api/**"
ignore-paths:
- "/service/health"
format-console-log-json: true启用后自动记录请求/响应日志,包含请求路径、参数、响应码、耗时等信息。
digitalhainan:
component:
exception:
report:
enable: true
report-type: DING_TALK
ding-talk:
url: "https://oapi.dingtalk.com/robot/send?access_token=xxx"digitalhainan:
component:
exception:
report:
enable: true
report-type: ALERT_PLATFORM
alert-platform:
apione-url: "https://apione.example.com"
ak: "your-ak"
sk: "your-sk"
apiname: "alert-api"
region: "cn-hainan"
integration-key: "your-key"digitalhainan:
web:
response:
mode: http_standard # 或 http_2xx(默认)http_2xx:所有异常返回 HTTP 200,通过 BaseResponse.state 判断成功/失败http_standard:按 HTTP 标准状态码返回(如 400/500)框架自动注册 /service/health 端点:
curl http://host:port/service/health
# 返回: {"code":"000000","data":null,"state":"UP"}禁用健康检查:
digitalhainan:
health:
enable: false原因: digitalhainan.component.swagger.enable 默认为 false。 解决: 在配置中设置 enable: true。
原因: 使用了自定义线程池而非框架提供的 taskAsyncParallelExecutor。 解决: 使用 @Async 注解(默认使用框架线程池),或确保自定义线程池使用 RunnableProxy / CallableProxy 包装任务。
原因: 确认 Dubbo SPI 配置文件存在 META-INF/dubbo/ 目录下。 解决: 框架已自动注册 ConsumerExceptionFilter 和 ProviderExceptionFilter,确保依赖版本一致。
原因: 配置值未使用 ENC(...) 包裹。 解决: 确保敏感配置格式为 ENC(密文)。
原因: @DynamicScheduled 需要 Spring Cloud 环境(EnvironmentChangeEvent)。 解决: 确保项目引入了 digitalhainan-config 或 Spring Cloud Context 依赖。
| digitalhainan-ms-common | Spring Boot | Spring Cloud | JDK | 说明 |
|---|---|---|---|---|
| 3.1.0-SNAPSHOT | 3.x | 2023.x | 21 | 当前版本 |
| 3.0.0 ~ 3.0.1 | 3.x | 2022.x | 21 | Spring Boot 3.x |
| 2.1.0 | 2.x | 2021.x | 8/11 | javax 命名空间 |
| 2.0.0 | 2.x | — | 8/11 | 初始版本 |