Skip to content
Datablau DAM数据治理产品手册

微服务 SDK 二次开发 ​

7.x 之后,产品微服务采用 backend-lib + server 分层。backend-lib 包含产品完整 MVC 逻辑并发布到 Nexus,server 只保留 Spring Boot 启动类、容器适配和交付配置。二开项目依赖对应的 backend-lib,在自己的模块中增加扩展 Controller、Service、Component、Entity 和 Repository。

这条路径适合需要运行在 DAM 服务进程内、复用产品事务和权限上下文的开发。只做跨系统查询或审批编排时,优先使用本章的 REST API 和独立适配服务。

1. 前置条件 ​

  • 获得 SDK 授权、目标版本的 backend-lib 和对应源码/接口说明。
  • 安装 JDK 17、Maven 3.8 或更高版本,并配置企业 Nexus 镜像。
  • 准备可访问的配置中心和服务注册中心。启动时通过环境变量或 JVM 参数注入地址、命名空间和凭据。
  • 为扩展建立独立 Git 分支,记录产品版本、SDK 版本和数据库迁移版本。

不要把配置中心密码、数据库密码或个人 Cookie 放进 pom.xml、启动脚本和日志。

2. 工程拆分 ​

text
datablau-<service>-backend-lib/   # 产品逻辑库,发布为 Maven artifact
datablau-<service>-server/       # 二开启动模块
  ├─ src/main/java/.../Application.java
  ├─ src/main/resources/
  └─ pom.xml

将原服务工程拆为两个模块:

  1. 原 backend 改成 datablau-<service>-backend,产物名改为 datablau-<service>-backend-lib,版本与产品版本保持一致。
  2. 新建 datablau-<service>-server,复制资源目录,把 Application 启动类从 lib 移入 server。
  3. 在 SpringApplication 和 JpaConfiguration 中加入扩展包扫描路径,预留 ext 包。
  4. server 只依赖 backend-lib 和运行容器 starter,不重新复制产品业务依赖。

backend-lib 的最小 Maven 结构:

xml
<artifactId>datablau-metadata-backend-lib</artifactId>
<packaging>jar</packaging>
<build>
  <resources>
    <resource>
      <directory>src/main/java</directory>
      <includes>
        <include>**/*.csv</include>
        <include>**/*.xml</include>
        <include>**/*.properties</include>
      </includes>
      <filtering>true</filtering>
    </resource>
    <resource>
      <directory>src/main/resources</directory>
      <includes><include>**/*.csv</include></includes>
      <filtering>true</filtering>
    </resource>
  </resources>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-compiler-plugin</artifactId>
    </plugin>
  </plugins>
</build>

server 的核心依赖和打包插件:

xml
<dependencies>
  <dependency>
    <groupId>com.datablau</groupId>
    <artifactId>datablau-metadata-backend-lib</artifactId>
    <version>${datablau.version}</version>
  </dependency>
</dependencies>
<build>
  <plugins>
    <plugin>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-maven-plugin</artifactId>
      <configuration><includeSystemScope>true</includeSystemScope></configuration>
      <executions><execution><goals><goal>repackage</goal></goals></execution></executions>
    </plugin>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-war-plugin</artifactId>
    </plugin>
  </plugins>
</build>

容器差异放在 server profile:默认使用 Spring Boot Tomcat,需要 BES 或 TongWeb 时只切换对应 starter profile,不改业务代码。

3. Bean 覆盖机制 ​

产品服务实现类和可扩展方法必须允许继承。产品 Bean 需要显式命名,并使用扩展 Bean 名称作为缺省条件:

java
@Service("userService")
@ConditionalOnMissingBean(name = "userServiceExt")
public class UserServiceImpl implements UserService {
  // 可被扩展的方法使用 protected 或 public
}

扩展类使用 XXXExt 命名:

java
@Service("userServiceExt")
public class UserServiceExtImpl extends UserServiceImpl {
  @Override
  public UserDto findById(Long id) {
    UserDto user = super.findById(id);
    // 增加企业自己的组合或校验
    return user;
  }
}

规则如下:

  • private 方法、内部类和无法重载的实现细节不能作为扩展点,应由产品版本提供 protected/public 的受支持入口。
  • 产品 Bean 的名称和扩展 Bean 的名称必须稳定,否则 Spring 可能同时创建两个实现。
  • 需要改变返回 DTO 时优先新增 xxxExt 方法和 DTO。直接把原接口返回类型改成子类,可能破坏其他微服务的远程反序列化。
  • 先调用 super 再补充属性适合轻量增强;需要改变 SQL、分页或事务语义时,应完整覆盖方法并补充契约测试。

4. 扩展属性的持久化 ​

产品表和产品 Repository 不直接修改。以给用户增加 hireDate 为例,创建独立扩展表,并用产品用户 ID 关联:

java
@Entity
@Table(name = "db_users_ext")
public class UserExt {
  @Id
  private Long userId;

  @Column(name = "hire_date")
  @Temporal(TemporalType.TIMESTAMP)
  private Date hireDate;
}

@Repository("userExtRepository")
public interface UserExtRepository extends CrudRepository<UserExt, Long> {
  @Query("select ue from UserExt ue where ue.userId in :userIds")
  List<UserExt> findByUserIds(@Param("userIds") Collection<Long> userIds);
}

扩展 Entity 必须位于 JpaConfiguration 扫描路径,例如 ...ext.jpa.entity 和 ...ext.jpa.repository。如果启动时出现 Entity 未 managed 或 Repository 找不到,先检查扫描包、实体主键和 profile,再检查数据库迁移是否已执行。

通过扩展 DTO 暴露属性:

java
public class UserExtDto extends UserDto {
  private Date hireDate;
  public UserExtDto(UserDto source) {
    BeanUtils.copyProperties(source, this);
  }
  // getter / setter
}

对列表接口,先调用产品服务拿到分页结果,再以业务主键批量查询扩展表并合并,禁止在循环中逐条查询。若远程调用方依赖原 DTO,提供新接口返回 UserExtDto,保留原接口兼容性。

5. 新增跨微服务接口 ​

以 Service A 提供、Service B 调用为例:

  1. 新建 datablau-servicea-<project>-api,只放共享 interface 和 DTO。
  2. 发布 API artifact 到 Nexus;Service A 与 Service B 分别声明同版本依赖。
  3. Service A 扩展 HttpExporterConfiguration,注册 HttpInvokerServiceExporter。
  4. Service B 在扩展配置中创建 RemoteServiceProxyFactoryBean,配置目标服务名、服务接口、服务 URL 和本地空实现。
  5. 在业务 Service 中注入接口,增加超时、重试、熔断和权限日志。

提供方示例:

java
@Configuration("httpExporterConfigurationExt")
public class HttpExporterConfigurationExt extends HttpExporterConfiguration {
  @Bean(name = "/ExampleInterface")
  public HttpInvokerServiceExporter exampleServiceExporter(ExampleInterface service) {
    HttpInvokerServiceExporter exporter = new HttpInvokerServiceExporter();
    exporter.setService(service);
    exporter.setServiceInterface(ExampleInterface.class);
    return exporter;
  }
}

调用方的代理配置必须使用目标服务的实际 context、端口和服务发现名称,不能复制开发环境 URL。共享 DTO 只放稳定字段,避免把产品内部 Entity 暴露为远程协议。

6. 构建、启动和调试 ​

bash
# 在父工程安装依赖和版本管理
mvn -f backend/datablau-parent/pom.xml install

# 编译全部后台模块
mvn -f backend/pom.xml install

# 只构建一个二开服务
mvn -pl datablau-metadata-server -am package

启动时配置 JDK 17、服务注册中心地址、命名空间、应用 home 和日志目录。配置中心账号通过环境变量注入,例如:

bash
export JAVA_HOME=/path/to/jdk-17
export METADATA_HOME=/opt/datablau_metadata
java -Xms2g -Xmx8g \
  -Dspring.cloud.nacos.username="$NACOS_USERNAME" \
  -Dspring.cloud.nacos.password="$NACOS_PASSWORD" \
  -Dspring.cloud.nacos.discovery.server-addr="$NACOS_ADDR" \
  -Dspring.cloud.nacos.discovery.namespace="$NACOS_NAMESPACE" \
  -Dlogging.file.path="$METADATA_HOME/logs" \
  -jar "$METADATA_HOME/app/datablau-metadata-server.jar"

本地调试流程:启动扩展服务并连接测试配置中心 → 将同一微服务的其他实例下线,只保留调试实例 → 登录 DAM → 用浏览器开发工具获取当前会话进行测试 → 用 Postman 或自动化测试调用扩展接口 → 检查 Bean、数据库、审计日志和返回结构。测试结束后恢复其他实例。

7. 发布和升级 ​

二开仓库建议按 backend/、frontend/ 和各微服务模块组织。发布时记录 backend-lib 版本、扩展版本、配置差异和数据库迁移。升级到 9.2 或后续版本时:先替换 lib 并编译 → 检查编译和 Bean 创建 → 回归原 API、扩展 API、远程调用和权限 → 执行数据库迁移 → 灰度启动 → 保留旧包和回滚配置。

升级检查重点包括方法签名、DTO 字段、Bean 名称、JPA 扫描路径、远程服务 URL、Parser SPI 和统计模型字段。每个版本必须有一组最小可重复的验收样本。