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

如何向MapStruct映射器传递额外参数?

我完全懂你现在的痛点——不想在OrderMapper的@AfterMapping里手动遍历填充OrderLineRequest的orderId,而是希望让OrderLineMapper直接拿到Order的ID来处理,这样代码更符合职责单一原则。其实MapStruct早就提供了传递额外参数的方案,就是用@Context注解,下面给你一步步的实现方案:

方案核心:用@Context传递上下文参数

@Context是MapStruct专门用来传递映射过程中额外数据的注解,它可以把父级映射中的对象(比如这里的Order)传递给子映射器(比如OrderLineMapper),而且集合映射时会自动把上下文传递给每个元素的映射方法。

1. 修改OrderLineMapper,添加带上下文的映射方法

我们需要调整OrderLineMapper的映射方法,让它能接收Order作为上下文参数,直接从Order里取ID赋值给OrderLineRequest:

@Mapper(componentModel = "spring")
public abstract class OrderLineMapper {
    @Mappings({
        @Mapping(target = "order_line_number", source = "orderLineNumber"),
        // 从上下文的Order对象中获取id,赋值给orderId
        @Mapping(target = "orderId", source = "order.id")
    })
    public abstract OrderLineRequest orderLineToOrderLineRequest(OrderLine orderLine, @Context Order order);

    // 逆映射保持你的原有逻辑即可
    @InheritInverseConfiguration
    public abstract OrderLine orderLineRequestToOrderLine(OrderLineRequest orderLineRequest);
}

2. 调整OrderLineMappers,传递上下文参数

因为OrderLineMappers是处理集合映射的,我们需要修改它的集合映射方法,添加@Context参数,这样MapStruct会自动把上下文传递给每个OrderLine的映射:

@Mapper(componentModel = "spring", uses = {OrderLineMapper.class})
public interface OrderLineMappers {
    List<OrderLine> orderLines(List<OrderLineRequest> orderLineRequest);

    // 添加@Context Order order参数,传递给单个元素的映射方法
    List<OrderLineRequest> orderLineRequests(List<OrderLine> orderLine, @Context Order order);
}

3. 修改OrderMapper,移除手动遍历逻辑并传递上下文

现在可以删掉原来的@AfterMapping方法,直接在映射注解里把当前的Order作为上下文传递给orderLines的映射:

@Mapper(componentModel = "spring", uses = {OrderLineMappers.class})
public abstract class OrderMapper {
    // 移除原来的@AfterMapping手动遍历代码

    @Mappings({
        @Mapping(source = "id", target = "orderId"),
        @Mapping(source = "orderNumber", target = "order_number"),
        // 用context = "this"把当前的Order对象传递给orderLineRequests方法
        @Mapping(source = "orderLines", target = "orderLines", context = "this")
    })
    public abstract OrderRequest orderToOrderRequest(Order order);

    @InheritInverseConfiguration
    public abstract Order orderRequestToOrder(OrderRequest orderRequest);
}

可选优化:直接传递OrderId而非整个Order对象

如果不需要传递整个Order对象,只想传orderId,可以简化一下:

  • OrderLineMapper的方法改成:
@Mappings({
    @Mapping(target = "order_line_number", source = "orderLineNumber"),
    @Mapping(target = "orderId", source = "orderId")
})
public abstract OrderLineRequest orderLineToOrderLineRequest(OrderLine orderLine, @Context String orderId);
  • OrderLineMappers的方法改成:
List<OrderLineRequest> orderLineRequests(List<OrderLine> orderLine, @Context String orderId);
  • OrderMapper的映射注解改成:
@Mapping(source = "orderLines", target = "orderLines", context = "id")

这样更轻量化,看你的业务需求选择即可。

注意事项

确保你的MapStruct版本在1.2.0及以上,@Context注解是从这个版本开始支持的,如果你用的是旧版本,需要先升级依赖。

这样改造后,映射逻辑就完全交给MapStruct处理了,不用再手动遍历集合,代码更简洁也更符合MapStruct的设计理念。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 10:17:35