如何配置MapStruct默认使用TagConverter中的longToTag方法?
问题场景
我定义了如下TagMapper接口:
@Mapper(uses = {PostConverter.class, TagConverter.class}) public interface TagMapper { void update(TagRequestDTO source, @MappingTarget Tag destination); Tag dtoToTag(TagRequestDTO dto); TagResponseDTO tagToDTO(Tag tag); Tag longToTag(Long id); }
同时定义了TagConverter接口及其实现类:
Converter接口
public interface TagConverter { Tag longToTag(Long id); Set<Long> fromTagsToLong(Set<Tag> tags); Set<Tag> fromLongsToTags(Set<Long> ids); }
实现类
@Component @RequiredArgsConstructor public class TagConverterImpl implements TagConverter { private final TagRepository repository; @Override public Tag longToTag(Long id) { return repository.findById(id).orElseThrow(() -> new EntityNotFoundException("Tag", id)); } }
请问是否可以配置MapStruct的行为,使其使用TagConverter中的longToTag方法而非自行生成?(无法使用默认方法和抽象类)我查阅过MapStruct文档,但未找到解决方案。
解决方案
可以通过以下几种方式实现需求:
方式1:移除Mapper中的同名方法
如果TagMapper中的longToTag方法只是为了供其他映射逻辑调用,大可不必在Mapper中重复定义。MapStruct会自动从@Mapper(uses = ...)指定的TagConverter中寻找匹配的转换方法,用于处理类似DTO中Long类型字段转Tag实体的场景。
方式2:使用@Delegate注解委托实现
若必须在TagMapper中保留longToTag方法,可通过@Delegate注解让该方法直接委托给TagConverter的实现类:
import org.mapstruct.Mapper; import org.mapstruct.MappingTarget; import org.mapstruct.decorator.Delegate; @Mapper(uses = {PostConverter.class, TagConverter.class}) public interface TagMapper { void update(TagRequestDTO source, @MappingTarget Tag destination); Tag dtoToTag(TagRequestDTO dto); TagResponseDTO tagToDTO(Tag tag); @Delegate Tag longToTag(Long id); }
由于你的TagConverterImpl已经添加了@Component注解被Spring管理,MapStruct生成的Mapper实现会自动注入TagConverter实例并调用其longToTag方法。
方式3:用@Named标记指定方法
- 给
TagConverter的longToTag方法添加@Named注解标记:
import org.mapstruct.Named; public interface TagConverter { @Named("tagConverterLongToTag") Tag longToTag(Long id); Set<Long> fromTagsToLong(Set<Tag> tags); Set<Tag> fromLongsToTags(Set<Long> ids); }
- 在
TagMapper的longToTag方法上添加同名@Named注解:
import org.mapstruct.Mapper; import org.mapstruct.MappingTarget; import org.mapstruct.Named; @Mapper(uses = {PostConverter.class, TagConverter.class}) public interface TagMapper { void update(TagRequestDTO source, @MappingTarget Tag destination); Tag dtoToTag(TagRequestDTO dto); TagResponseDTO tagToDTO(Tag tag); @Named("tagConverterLongToTag") Tag longToTag(Long id); }
这样MapStruct会优先选用uses集合中带有对应@Named标记的方法,而非自行生成实现。
注意:确保使用的MapStruct版本在1.4及以上,上述注解在旧版本中可能不支持。
内容的提问来源于stack exchange,提问作者Mihena
相关产品推荐
相关产品推荐

