Skip to content
返回

后端脚手架

脚手架

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

概述
后端脚手架

digitalhainan-ms-common ​

本文档用于指导在目标项目中完成 digitalhainan-ms-common 模块集成。

执行顺序:

  1. 先完成「4.1.2 快速集成」的全部步骤(必须)
  2. 根据业务需求,查阅「功能集成决策索引」选择对应路径,逐项实现
  3. 遇到配置问题时参考「4.1.3 配置属性参考」
  4. 出现异常时查阅「4.1.6 常见问题」

代码约定: 所有代码示例均包含完整 import 路径和类声明,可直接用于代码生成。


4.1.1 模块简介 ​

digitalhainan-ms-common 是数字海南框架的 微服务公共组件,为所有微服务提供统一的基础能力:

  • i18n 国际化 — 基于 Spring MessageSource 的异常消息国际化,@AppI18n 注解自动翻译响应字段
  • Dubbo 增强 — Dubbo 异常拦截、参数校验、Consumer/Provider 异常透传、RPC 链路追踪
  • Swagger/Knife4j — OpenAPI 3.0 文档自动生成,Basic Auth 访问控制
  • Web 增强 — WebContextRootFilter、MDC 请求追踪、验证码、健康检查、版本信息
  • 全局异常处理 — 统一异常响应格式,支持 http_2xx / http_standard 两种响应模式
  • Jasypt SM4 加密 — 配置文件敏感字段 SM4 加解密,提供 /api/rest/jasypt/encrypt 接口
  • 异步线程池 — 可配置线程池(核心/最大线程数、队列容量、拒绝策略),自动传递 MDC 上下文
  • 动态定时任务 — @DynamicScheduled 注解,支持运行时动态修改 Cron 表达式(需 Spring Cloud)
  • RestTemplate — 封装 HTTP 连接池(HttpClient5),支持 HTTPS、UTF-8、Header 透传
  • 链路追踪 — SkyWalking TraceId 集成 MDC,TraceContext 工具类
  • HTTP 请求日志 — AOP + Interceptor 双模式请求日志记录
  • 异常上报 — 异常事件驱动,支持钉钉机器人 / 告警平台上报

Maven 坐标:

xml
<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


4.1.2 快速集成 ​

4.1.2.1 确认父 POM ​

xml
<parent>
    <groupId>cn.com.digitalhainan</groupId>
    <artifactId>digitalhainan-pom</artifactId>
    <version>3.1.0-SNAPSHOT</version>
</parent>

4.1.2.2 添加依赖 ​

xml
<dependencies>
    <dependency>
        <groupId>cn.com.digitalhainan</groupId>
        <artifactId>ms-common</artifactId>
    </dependency>
</dependencies>

4.1.2.3 基础配置(application.yml) ​

yaml
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

4.1.2.4 验证清单 ​

  • [ ] Spring Boot 启动成功
  • [ ] 访问 /service/health 返回 {"state":"UP"}
  • [ ] 访问 /doc.html 可查看 Swagger 文档(如已启用)
  • [ ] 异常响应统一为 BaseResponse 格式

4.1.3 配置属性参考 ​

4.1.3.1 全局配置 ​

配置键类型默认值说明
digitalhainan.enable-mdc-handlerBooleantrue是否启用 MDC 请求追踪过滤器
digitalhainan.enable-exception-handlerBooleantrue是否启用全局异常处理
digitalhainan.base-packageString—基础包路径

4.1.3.2 Web 响应模式 ​

配置键类型默认值说明
digitalhainan.web.response.modeEnumhttp_2xx响应模式:http_2xx(所有异常返回 200)/ http_standard(按 HTTP 标准状态码)

4.1.3.3 Swagger 配置 ​

配置键类型默认值说明
digitalhainan.component.swagger.enableBooleanfalse是否启用 Swagger 文档
digitalhainan.component.swagger.titleStringDigitalhainan快速集成Swagger文档文档标题
digitalhainan.component.swagger.descriptionString—文档描述
digitalhainan.component.swagger.versionStringv1.0文档版本
digitalhainan.component.swagger.base-packageString—扫描包路径
digitalhainan.component.swagger.licenseStringdigtitalhainan许可证
digitalhainan.component.swagger.contact.nameStringHl联系人
digitalhainan.component.swagger.contact.emailString—联系邮箱
digitalhainan.component.swagger.authorization.nameStringAuthorizationToken Header 名称
digitalhainan.component.swagger.authorization.descriptionStringuser tokenToken 描述
digitalhainan.component.swagger.basic.enableBooleantrue是否启用 Basic Auth
digitalhainan.component.swagger.basic.usernameStringadminBasic Auth 用户名
digitalhainan.component.swagger.basic.passwordStringSzhn@123Basic Auth 密码

4.1.3.4 Dubbo 配置 ​

配置键类型默认值说明
digitalhainan.component.dubbo.validation-expressionString—Dubbo 拦截切面表达式(如 execution(* cn.com.digitalhainan..*.*(..)))
digitalhainan.component.dubbo.exception-coverEnumTHROW_EXCEPTION异常覆盖策略:THROW_EXCEPTION / COVER_RESPONSE

4.1.3.5 异步线程池配置 ​

配置键类型默认值说明
digitalhainan.component.task.task-async-parallel-executor.core-pool-sizeInteger10核心线程数
digitalhainan.component.task.task-async-parallel-executor.maximum-pool-sizeInteger20最大线程数
digitalhainan.component.task.task-async-parallel-executor.keep-alive-secondsInteger3600空闲线程存活时间(秒)
digitalhainan.component.task.task-async-parallel-executor.queue-capacityIntegerMAX_VALUE队列容量
digitalhainan.component.task.task-async-parallel-executor.thread-name-prefixStringdigitalhainan-taskExecutor-线程名前缀
digitalhainan.component.task.task-async-parallel-executor.rejected-execution-strategyEnumCALLER_RUNS_POLICY拒绝策略:ABORT_POLICY / DISCARD_POLICY / CALLER_RUNS_POLICY / DISCARD_OLDEST_POLICY

4.1.3.6 RestTemplate 配置 ​

配置键类型默认值说明
digitalhainan.component.rest.connect-time-outInteger-1连接超时(毫秒),-1 为不限制
digitalhainan.component.rest.read-time-outInteger-1读取超时(毫秒)
digitalhainan.component.rest.max-total-connectInteger0最大连接数(>0 启用连接池)
digitalhainan.component.rest.max-connect-per-routeInteger0每路由最大连接数
digitalhainan.component.rest.time-to-liveInteger120000连接存活时间(毫秒)
digitalhainan.component.rest.validate-after-inactivityInteger30000不活动后验证间隔(毫秒)

4.1.3.7 HTTP 请求日志 ​

配置键类型默认值说明
digitalhainan.component.request-logging.enableBooleanfalse是否启用请求日志
digitalhainan.component.request-logging.logging-path-prefixList["/**"]日志拦截路径前缀
digitalhainan.component.request-logging.ignore-pathsList[]忽略路径
digitalhainan.component.request-logging.format-console-log-jsonBooleantrue控制台日志是否 JSON 格式

4.1.3.8 异常上报 ​

配置键类型默认值说明
digitalhainan.component.exception.report.enableBooleanfalse是否启用异常上报
digitalhainan.component.exception.report.report-typeEnumDING_TALK上报类型:DING_TALK / ALERT_PLATFORM
digitalhainan.component.exception.report.ding-talk.urlString—钉钉机器人 Webhook URL
digitalhainan.component.exception.report.alert-platform.apione-urlString—告警平台 URL
digitalhainan.component.exception.report.alert-platform.akString—ApiOne AK
digitalhainan.component.exception.report.alert-platform.skString—ApiOne SK
digitalhainan.component.exception.report.alert-platform.apinameString—ApiOne API 名称
digitalhainan.component.exception.report.alert-platform.regionString—区域
digitalhainan.component.exception.report.alert-platform.integration-keyString—集成密钥

4.1.3.9 健康检查 ​

配置键类型默认值说明
digitalhainan.health.enableBooleantrue是否启用健康检查端点 /service/health

4.1.4 核心功能使用 ​

功能集成决策索引 ​

需求场景参考章节
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
链路追踪 TraceId4.9 链路追踪
HTTP 请求日志4.10 请求日志
异常上报(钉钉/告警平台)4.11 异常上报
Web 响应模式切换4.12 Web 响应模式
健康检查4.13 健康检查

4.1.4.1 i18n 国际化 ​

4.1.1 配置 i18n 资源文件 ​

在 src/main/resources/i18n/ 下创建属性文件:

properties
# messages_zh_CN.properties
ERR_RETRY=请稍后重试
ERR_INVALID_PARAMS=无效请求参数
UNAUTHORIZED=无权访问
BUSINESS_ERROR_001=用户 {0} 不存在

4.1.2 使用 @AppI18n 注解自动翻译 ​

java
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("操作成功");
    }
}

4.1.3 自定义 IBusinessExceptionI18nMessage ​

java
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;
            }
        };
    }
}

4.1.4.2 Dubbo 增强 ​

4.2.1 启用 Dubbo 异常拦截 ​

yaml
digitalhainan:
  component:
    dubbo:
      validation-expression: "execution(* cn.com.digitalhainan..dubbo.*.*(..))"
      exception-cover: THROW_EXCEPTION  # 或 COVER_RESPONSE
  • THROW_EXCEPTION — 使用 ValidationInterceptor,直接抛出异常
  • COVER_RESPONSE — 使用 DubboExceptionInterceptor,将异常转为 BaseResponse 返回

4.2.2 Dubbo Filter 自动注册 ​

Consumer/Provider 异常 Filter 通过 SPI 自动注册,无需额外配置:

META-INF/dubbo/org.apache.dubbo.rpc.cluster.filter.ClusterFilter
META-INF/dubbo/org.apache.dubbo.rpc.Filter

4.1.4.3 Swagger/Knife4j ​

yaml
digitalhainan:
  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 登录后查看文档。


4.1.4.4 全局异常处理 ​

框架自动接管 /error 路径,所有异常统一转为 BaseResponse 格式:

json
{
  "code": "ERR_RETRY",
  "message": "请稍后重试",
  "data": null,
  "requestId": "trace-id-xxx",
  "timestamp": "2024-01-01T00:00:00"
}

自定义异常解析器:

java
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) {
                // 自定义调试信息提取
            }
        };
    }
}

4.1.4.5 Jasypt SM4 加密 ​

4.5.1 配置文件中加密敏感数据 ​

yaml
spring:
  datasource:
    password: ENC(加密后的密文)

框架使用 JasyptSm4Encryptor(SM4 CBC 模式)自动解密 ENC(...) 包裹的值。

4.5.2 调用加密接口 ​

bash
# 加密明文
curl "http://host:port/api/rest/jasypt/encrypt?message=123456"

# 返回
{
  "code": "000000",
  "data": "加密后的十六进制字符串",
  "state": "UP"
}

4.1.4.6 异步线程池 ​

java
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");
    }
}

配置线程池参数:

yaml
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

4.1.4.7 动态定时任务 ​

需要 Spring Cloud 环境(EnvironmentChangeEvent)

java
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 值后,定时任务自动重新调度。


4.1.4.8 RestTemplate ​

java
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);
    }
}

4.1.4.9 链路追踪 ​

java
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();
    }
}

4.1.4.10 请求日志 ​

yaml
digitalhainan:
  component:
    request-logging:
      enable: true
      logging-path-prefix:
        - "/api/**"
      ignore-paths:
        - "/service/health"
      format-console-log-json: true

启用后自动记录请求/响应日志,包含请求路径、参数、响应码、耗时等信息。


4.1.4.11 异常上报 ​

4.11.1 钉钉机器人上报 ​

yaml
digitalhainan:
  component:
    exception:
      report:
        enable: true
        report-type: DING_TALK
        ding-talk:
          url: "https://oapi.dingtalk.com/robot/send?access_token=xxx"

4.11.2 告警平台上报 ​

yaml
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"

4.1.4.12 Web 响应模式 ​

yaml
digitalhainan:
  web:
    response:
      mode: http_standard  # 或 http_2xx(默认)
  • http_2xx:所有异常返回 HTTP 200,通过 BaseResponse.state 判断成功/失败
  • http_standard:按 HTTP 标准状态码返回(如 400/500)

4.1.4.13 健康检查 ​

框架自动注册 /service/health 端点:

bash
curl http://host:port/service/health
# 返回: {"code":"000000","data":null,"state":"UP"}

禁用健康检查:

yaml
digitalhainan:
  health:
    enable: false

4.1.5 版本变更记录 ​

v3.1.0(当前版本) ​

  • JasyptSm4Encryptor 接口加密改造
  • 支持 HTTP 状态码响应模式(http_standard)
  • Dubbo 异常拦截增强
  • 动态定时任务 @DynamicScheduled
  • 异常上报(钉钉/告警平台)
  • 去重 Nacos 配置

v3.0.1 ​

  • 合并 v3.0.0 修复

v3.0.0 ​

  • Spring Boot 3.x / JDK 21 适配
  • Jakarta 命名空间迁移
  • Knife4j OpenAPI 3 Jakarta 升级
  • Token 策略优化

v2.1.0 ​

  • Dubbo 基础配置
  • 异步线程池优化

v2.0.0 ​

  • 初始版本

4.1.6 常见问题 ​

Q1:Swagger 文档无法访问? ​

原因: digitalhainan.component.swagger.enable 默认为 false。 解决: 在配置中设置 enable: true。

Q2:异步任务中 traceId 丢失? ​

原因: 使用了自定义线程池而非框架提供的 taskAsyncParallelExecutor。 解决: 使用 @Async 注解(默认使用框架线程池),或确保自定义线程池使用 RunnableProxy / CallableProxy 包装任务。

Q3:Dubbo 调用异常未透传到 Consumer? ​

原因: 确认 Dubbo SPI 配置文件存在 META-INF/dubbo/ 目录下。 解决: 框架已自动注册 ConsumerExceptionFilter 和 ProviderExceptionFilter,确保依赖版本一致。

Q4:Jasypt 加密的配置未解密? ​

原因: 配置值未使用 ENC(...) 包裹。 解决: 确保敏感配置格式为 ENC(密文)。

Q5:动态定时任务不生效? ​

原因: @DynamicScheduled 需要 Spring Cloud 环境(EnvironmentChangeEvent)。 解决: 确保项目引入了 digitalhainan-config 或 Spring Cloud Context 依赖。


4.1.7 版本兼容性矩阵 ​

digitalhainan-ms-commonSpring BootSpring CloudJDK说明
3.1.0-SNAPSHOT3.x2023.x21当前版本
3.0.0 ~ 3.0.13.x2022.x21Spring Boot 3.x
2.1.02.x2021.x8/11javax 命名空间
2.0.02.x—8/11初始版本

Power By 数字海南