MapStruct代码重复问题:仅需为Token字段应用generateToken方法
解决MapStruct自动为login字段调用generateToken的问题
问题根源在于你在@Mapper注解中指定了uses = MapperGenerateToken.class,MapStruct会自动扫描该类中的转换方法,当发现generateToken的输入输出类型与login字段的类型匹配时,就会自动将其应用到login字段的转换上。
以下是两种可行的解决方式:
方式一:移除@Mapper的uses属性(推荐)
直接去掉@Mapper中的uses配置,仅在token字段的@Mapping中通过expression显式调用generateToken方法。这样MapStruct不会自动将该方法应用到其他字段。
修改后的Mapper代码:
public interface TelemarketerAccountMapper { TelemarketerAccountMapper INSTANCE = Mappers.getMapper(TelemarketerAccountMapper.class); @Mapping(expression = "java(MapperGenerateToken.generateToken(assistant.getLogin()))", target = "token") @Mapping(source = "assistant.login", target = "login") AuthenticatedTelemarketerAccount map(TelemarketerAccount assistant); }
生成的代码会变为:
@Override public AuthenticatedTelemarketerAccount map(TelemarketerAccount assistant) { if (assistant == null) { return null; } AuthenticatedTelemarketerAccount authenticatedTelemarketerAccount = new AuthenticatedTelemarketerAccount(); authenticatedTelemarketerAccount.setLogin(assistant.getLogin()); authenticatedTelemarketerAccount.setToken(MapperGenerateToken.generateToken(assistant.getLogin())); return authenticatedTelemarketerAccount; }
方式二:使用@Named限定转换方法
如果需要保留uses = MapperGenerateToken.class的配置(比如该类中有其他需要复用的转换方法),可以通过@Named注解标记generateToken,并在token字段上显式指定使用该方法,同时为login字段指定默认的 identity 转换。
步骤1:为generateToken添加@Named注解
import org.mapstruct.Named; public class MapperGenerateToken { @Named("generateToken") public static String generateToken(String login) { // 你的token生成逻辑 return login + "_token"; } }
步骤2:修改Mapper接口
import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.Named; @Mapper(uses = MapperGenerateToken.class) public interface TelemarketerAccountMapper { TelemarketerAccountMapper INSTANCE = Mappers.getMapper(TelemarketerAccountMapper.class); @Mapping(target = "token", source = "login", qualifiedByName = "generateToken") @Mapping(target = "login", source = "login", qualifiedByName = "identity") AuthenticatedTelemarketerAccount map(TelemarketerAccount assistant); // 定义identity转换方法,直接返回原对象 @Named("identity") default <T> T identity(T value) { return value; } }
这样MapStruct会仅对token字段使用generateToken方法,login字段则通过identity方法直接赋值,不会调用generateToken。
内容的提问来源于stack exchange,提问作者Willian Tártaro
相关产品推荐
相关产品推荐

