You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在MapStruct中实现Mapper复用?

MapStruct中复用Mapper的几种方案

针对你提到的基于Spring组件模型的Mapper复用需求,以下是几种实用的实现方案:

方案一:提取公共映射逻辑到基础Mapper

将两个Mapper中重复的映射规则抽离到一个基础Mapper接口,业务Mapper通过继承该接口复用逻辑,便于统一维护。

// 基础Mapper:定义公共映射规则
public interface BaseProductoRepositoryMapper {
    @BeanMapping(ignoreByDefault = true)
    @Mapping(source = "convenioResponse.id", target = "id")
    @Mapping(source = "convenioResponse.cantidad", target = "cantidad")
    ProductoRepositoryEntity mapConvenioToEntity(ConvenioResponse convenioResponse);
}

// 原ProductoToRepositoryMapper继承基础Mapper
@Mapper(componentModel = "spring")
public interface ProductoToRepositoryMapper extends BaseProductoRepositoryMapper {
    // 复用基础Mapper的方法,也可以保留原有方法名做适配
    default ProductoRepositoryEntity map(ConvenioResponse convenioResponse) {
        return mapConvenioToEntity(convenioResponse);
    }
}

// OtherToRepositoryMapper继承基础Mapper,实现自定义转换入口
@Mapper(componentModel = "spring")
public interface OtherToRepositoryMapper extends BaseProductoRepositoryMapper {
    default ProductoRepositoryEntity map(OtherClass otherClass) {
        // 从OtherClass中获取ConvenioResponse,调用基础映射方法
        return mapConvenioToEntity(otherClass.getConvenioResponse());
    }
}

方案二:直接注入并调用已有Mapper

利用Spring的依赖注入特性,在目标Mapper中注入已有的Mapper实例,直接调用其映射方法。

@Mapper(componentModel = "spring")
public interface OtherToRepositoryMapper {
    // 注入ProductoToRepositoryMapper(Spring环境下MapStruct会自动处理注入)
    @Autowired
    ProductoToRepositoryMapper productoToRepositoryMapper;

    default ProductoRepositoryEntity map(OtherClass otherClass) {
        // 直接复用已有Mapper的映射逻辑
        return productoToRepositoryMapper.map(otherClass.getConvenioResponse());
    }
}

注意:原ProductoToRepositoryMapper中的INSTANCE字段可以删除,因为Spring会统一管理Bean实例,无需手动通过Mappers.getMapper()获取。

方案三:使用@Mapper的uses属性声明依赖

通过MapStruct原生的uses属性指定当前Mapper依赖的其他Mapper,框架会自动处理实例化与注入,实现映射逻辑复用。

// 移除原ProductoToRepositoryMapper中的INSTANCE字段
@Mapper(componentModel = "spring")
public interface ProductoToRepositoryMapper {
    @BeanMapping(ignoreByDefault = true)
    @Mapping(source = "convenioResponse.id", target = "id")
    @Mapping(source = "convenioResponse.cantidad", target = "cantidad")
    ProductoRepositoryEntity map(ConvenioResponse convenioResponse);
}

// 使用uses属性声明依赖的Mapper
@Mapper(componentModel = "spring", uses = ProductoToRepositoryMapper.class)
public interface OtherToRepositoryMapper {
    // 定义从OtherClass到ConvenioResponse的转换
    @Mapping(source = ".", target = ".")
    ConvenioResponse extractConvenio(OtherClass otherClass);

    // 复用ProductoToRepositoryMapper的映射方法
    default ProductoRepositoryEntity map(OtherClass otherClass) {
        ConvenioResponse convenioResponse = extractConvenio(otherClass);
        return map(convenioResponse);
    }

    // 该方法会委托给ProductoToRepositoryMapper的实现
    ProductoRepositoryEntity map(ConvenioResponse convenioResponse);
}

方案选择建议

  • 若多个Mapper存在大量重复映射规则,优先选择方案一,统一维护逻辑,降低后续修改成本。
  • 若仅需复用单个Mapper的特定方法,方案二更直接,逻辑依赖关系清晰。
  • 希望借助MapStruct原生机制管理Mapper依赖时,方案三是更符合框架设计的选择。

内容的提问来源于stack exchange,提问作者sansumng tablet2022

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 03:40:22