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

MapStruct映射器内调用其他映射器及方法跨映射复用问题

解决方案

场景回顾

源DTO

AuditClass{
  protected ZonedDateTime creationDateTime;
  protected ZonedDateTime lastUpdateDateTime;
}

LocationRequest extends AuditClass{
 //some fields
}

目标DTO

CachedLocation{
//some fields
protected LocalDateTime updateTime;
}

当前映射器代码

@Mapper(componentModel = "spring", uses = {LocalAndZonedDateTimeMapper.class})
public interface LocationRequestResponseMapper{

  @Mapping(source = ".", target = "updateTime", qualifiedByName = "getUpdateTime")
  CachedLocation toCachedLocation(LocationRequest location);

  //问题2:我希望将该方法迁移至另一个映射器,以便在所有请求映射中复用,是否有可行方案?
  @Named("getUpdateTime")
  default LocalDateTime getUpdateTime(AuditClass request) {

    //问题1:我希望在此方法中使用LocalAndZonedDateTimeMapper,但当前映射器是接口,无法使用抽象类,该如何实现?
    if (request.getCreationDateTime() != null) {
      return localAndZonedDateTimeMapper.toLocalDateTime(request.getCreationDateTime());
    } else if (request.getLastUpdateDateTime() != null) {
      return localAndZonedDateTimeMapper.toLocalDateTime(request.getLastUpdateDateTime());

    }
    return null;
  }
}

问题1解决方案:在接口default方法中使用LocalAndZonedDateTimeMapper

因为映射器使用了spring组件模型,可通过在接口中添加一个抽象方法并标记@Autowired来获取LocalAndZonedDateTimeMapper实例,然后在default方法中调用该方法使用:

@Mapper(componentModel = "spring", uses = {LocalAndZonedDateTimeMapper.class})
public interface LocationRequestResponseMapper{

  @Mapping(source = ".", target = "updateTime", qualifiedByName = "getUpdateTime")
  CachedLocation toCachedLocation(LocationRequest location);

  // 声明抽象方法,由Spring自动注入mapper实例
  @Autowired
  LocalAndZonedDateTimeMapper getLocalAndZonedDateTimeMapper();

  @Named("getUpdateTime")
  default LocalDateTime getUpdateTime(AuditClass request) {
    LocalAndZonedDateTimeMapper mapper = getLocalAndZonedDateTimeMapper();
    if (request.getCreationDateTime() != null) {
      return mapper.toLocalDateTime(request.getCreationDateTime());
    } else if (request.getLastUpdateDateTime() != null) {
      return mapper.toLocalDateTime(request.getLastUpdateDateTime());
    }
    return null;
  }
}

MapStruct生成的Spring实现类会自动处理这个抽象方法的注入,无需额外配置。


问题2解决方案:独立复用类实现全局方法复用

由于无法将方法移入LocalAndZonedDateTimeMapper(循环依赖),可以创建一个独立的审计时间处理映射器,将getUpdateTime方法迁移至此,其他需要该逻辑的映射器通过uses属性引入即可:

1. 创建独立的AuditTimeMapper

@Mapper(componentModel = "spring", uses = {LocalAndZonedDateTimeMapper.class})
public interface AuditTimeMapper {

  @Autowired
  LocalAndZonedDateTimeMapper getLocalAndZonedDateTimeMapper();

  @Named("getUpdateTime")
  default LocalDateTime getUpdateTime(AuditClass request) {
    LocalAndZonedDateTimeMapper mapper = getLocalAndZonedDateTimeMapper();
    if (request.getCreationDateTime() != null) {
      return mapper.toLocalDateTime(request.getCreationDateTime());
    } else if (request.getLastUpdateDateTime() != null) {
      return mapper.toLocalDateTime(request.getLastUpdateDateTime());
    }
    return null;
  }
}

2. 修改原映射器引入AuditTimeMapper

@Mapper(componentModel = "spring", uses = {AuditTimeMapper.class})
public interface LocationRequestResponseMapper{

  @Mapping(source = ".", target = "updateTime", qualifiedByName = "getUpdateTime")
  CachedLocation toCachedLocation(LocationRequest location);
}

3. 其他映射器复用方式

任何需要处理AuditClass时间转换的映射器,只需在@Mapper的uses中添加AuditTimeMapper.class,并通过qualifiedByName = "getUpdateTime"指定方法即可,无需重复编写逻辑。

这种方式既避免了循环依赖,又实现了逻辑的全局复用,符合模块化设计原则。


内容的提问来源于stack exchange,提问作者Rahul verma

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 01:11:08