MapStruct 中 @BeforeMapping 和 @AfterMapping 注解的使用详解

news/2025/3/27 12:18:06/

在使用 MapStruct 进行对象映射时,@BeforeMapping@AfterMapping这两个注解能让开发者在映射前后执行自定义逻辑,极大地增强了映射的灵活性,满足多样化的业务需求。

一、@BeforeMapping 注解

1.1 作用

@BeforeMapping用于在映射方法执行前进行预处理操作。它允许开发者对源对象或其他相关数据进行修改、验证等操作,确保映射过程能基于符合预期的数据进行。

1.2 使用场景

在一个电商系统中,订单对象Order有个创建时间字段creationTime,类型为Date。在映射到用于展示的OrderDto时,需要将creationTime格式化为特定的字符串格式(如 "yyyy-MM-dd HH:mm:ss")。此时就可以使用@BeforeMapping注解在映射前进行格式化处理。

1.3 示例代码

import org.mapstruct.BeforeMapping;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import java.text.SimpleDateFormat;
import java.util.Date;@Mapper
public interface OrderMapper {OrderMapper INSTANCE = Mappers.getMapper(OrderMapper.class);@BeforeMappingdefault void formatCreationTime(Order order) {if (order != null && order.getCreationTime() != null) {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String formattedTime = sdf.format(order.getCreationTime());order.setFormattedCreationTime(formattedTime);}}OrderDto orderToOrderDto(Order order);
}class Order {private Date creationTime;private String formattedCreationTime;// 省略getter和setter
}class OrderDto {private String creationTime;// 省略getter和setter
}

在上述代码中,formatCreationTime方法被@BeforeMapping注解修饰。在执行orderToOrderDto映射方法前,会先调用formatCreationTime方法对Order对象的creationTime进行格式化,并将格式化后的结果存储在formattedCreationTime字段中,后续映射时就可以将formattedCreationTime映射到OrderDtocreationTime字段。

二、@AfterMapping 注解

2.1 作用

@AfterMapping用于在映射方法执行后进行后处理操作。通常用于对映射后的目标对象进行额外的修改、填充等操作,使目标对象更符合业务要求。

2.2 使用场景

还是在电商系统中,映射得到的OrderDto对象需要添加一个表示订单状态描述的字段statusDescription,该描述根据订单的实际状态(如已支付、已发货等)动态生成。由于这个描述信息在源对象Order中并不直接存在,所以可以在映射完成后使用@AfterMapping来添加这个字段。

2.3 示例代码

java">import org.mapstruct.AfterMapping;
import org.mapstruct.Mapper;
import org.mapstruct.MappingTarget;
import org.mapstruct.factory.Mappers;@Mapper
public interface OrderMapper {OrderMapper INSTANCE = Mappers.getMapper(OrderMapper.class);OrderDto orderToOrderDto(Order order);@AfterMappingdefault void addStatusDescription(Order order, @MappingTarget OrderDto orderDto) {if (order != null && orderDto != null) {if ("PAID".equals(order.getStatus())) {orderDto.setStatusDescription("订单已支付");} else if ("SHIPPED".equals(order.getStatus())) {orderDto.setStatusDescription("订单已发货");} else {orderDto.setStatusDescription("未知状态");}}}
}class Order {private String status;// 省略getter和setter
}class OrderDto {private String statusDescription;// 省略getter和setter
}

在这段代码里,addStatusDescription方法被@AfterMapping注解修饰,并且接收源对象Order和目标对象OrderDto(通过@MappingTarget注解标注目标对象)作为参数。在orderToOrderDto映射方法执行完毕后,会调用addStatusDescription方法,根据Order对象的status字段为OrderDto对象添加statusDescription字段。

三、注意事项

  1. 方法签名规范:被@BeforeMapping@AfterMapping注解的方法必须是default方法,且方法签名要符合要求。@BeforeMapping方法一般接收源对象作为参数(可以有多个源对象相关参数),@AfterMapping方法除了可以接收源对象,还需要通过@MappingTarget注解标注目标对象作为参数。
  2. 顺序问题:多个@BeforeMapping方法和多个@AfterMapping方法的执行顺序是不确定的。如果有严格的顺序要求,建议将相关逻辑合并到一个方法中。
  3. 异常处理:在@BeforeMapping@AfterMapping方法中抛出的异常会中断映射过程,所以需要根据业务需求合理处理异常,避免影响整个映射流程。

通过合理运用@BeforeMapping@AfterMapping注解,开发者可以在 MapStruct 的对象映射过程中,轻松实现各种复杂的业务逻辑,让映射功能更加完善和灵活。


http://www.ppmy.cn/news/1573067.html

相关文章

如何将模型长度扩展到100万:Llama 3的NTK-aware插值技术解析 小学生都懂的

好的,以下是对 Llama 3 如何通过 NTK-aware 插值 调整位置编码以扩展上下文长度到 100 万的详细原理解释: 1. RoPE(旋转位置编码)的原理 RoPE 是一种用于 Transformer 模型的位置编码方法,它通过旋转向量来注入位置信…

Golang 语言的内存管理

转载:Golang 语言的内存管理 内存分布 什么是虚拟内存? 计算机系统内存管理的一种技术。 每个进程都拥有独立的、连续的、统一的的虚拟地址空间。 通过 MMU 和物理内存映射,高效使用物理内存。 64 位 linux 进程内存分布情况 理论上有 16E 的…

怎么理解 Spring Boot 的约定优于配置 ?

在传统的 Spring 开发中,大家可能都有过这样的经历:项目还没开始写几行核心业务代码,就已经在各种配置文件中耗费了大量时间。比如,要配置数据库连接,不仅要在 XML 文件里编写冗长的数据源配置,还要处理事务…

金融交易算法单介绍

0.背景 股票交易时,常见的订单类型有基础订单和条件订单。 基础订单 市价单限价单碎股单等等 条件订单 止损市价单止损限价单触及市价单(止盈)触及限价单(止盈)跟踪止损市价单跟踪止损限价单等等 除了基础订单和…

rustdesk编译修改名字

最近,我用Rust重写了一个2W行C代码的linux内核模块。在此记录一点经验。我此前没写过内核模块,认识比较疏浅,有错误欢迎指正。 为什么要重写? 这个模块2W行代码量看起来不多,却在线上时常故障,永远改不完。…

Qt中基于开源库QRencode生成二维码(附工程源码链接)

目录 1.QRencode简介 2.编译qrencode 3.在Qt中直接使用QRencode源码 3.1.添加源码 3.2.用字符串生成二维码 3.3.用二进制数据生成二维码 3.4.界面设计 3.5.效果展示 4.注意事项 5.源码下载 1.QRencode简介 QRencode是一个开源的库,专门用于生成二维码&…

论文阅读_用于低频隔振的高负刚度新型阵列磁性弹簧的分析与设计_3

前言 提醒: 文章内容为方便作者自己后日复习与查阅而进行的书写与发布,其中引用内容都会使用链接表明出处(如有侵权问题,请及时联系)。 其中内容多为一次书写,缺少检查与订正,如有问题或其他拓展…

C# SpinLock 类 使用详解

总目录 前言 SpinLock 是 C# 中一种轻量级的自旋锁,属于 System.Threading 命名空间,专为极短时间锁竞争的高性能场景设计。它通过忙等待(自旋)而非阻塞线程来减少上下文切换开销,适用于锁持有时间极短(如…