这是我的上下文:我使用byteBuddy动态生成一个类,该类根据外部配置将对象转换为另一个对象。我遇到了一些问题,我想找到一个替代方案,就是我发现MapStruct的方法。
所以我尝试构建简单的映射器,我想知道是否有可能自定义注释以添加转换函数。例如,我希望:
@Mapping(
source = "mySourceField",
sourceType = "String",
target = "myTargetField",
targetType = "Integer",
transformation = {"toInteger", "toSquare"}
),
在mapper实现上我会有类似的东西:
public TypeDest toSiteCatTag(TypeSrc obj) {
if ( obj == null ) {
return null;
}
TypeDest objDest = new TypeDest();
objDest.myTargetField = Formatter.toSquare(
Formatter.toInteger(obj.mySourceField));
return objDest;
}
如果有人可以帮助我实现这一点,我将不胜感激,这将为我节省很多时间。
提前致谢。
答案 0 :(得分:13)
如果在运行时没有生成2种类型mySecondResolver
和TypeDest
,即它们是您编译的类,那么您可以实现您想要的。 MapStruct在运行时不起作用,因为它是一个Annotation Processor并生成java代码。如果存在一些问题,例如您尝试映射不存在的字段或存在不明确的映射方法,则会出现编译时错误。
它看起来像:
TypeSrc
有一种方法可以在映射器中没有自定义方法的情况下执行此操作,但您需要在某处应用@Mapper
public interface MyMapper {
@Mapping(source = "mySourceField", target = "myTargetField", qualifiedByName = "myTransformation")// or you can use a custom @Qualifier annotation with qualifiedBy
TypeDest toSiteCatTag(TypeSrc obj);
@Named("myTransformation")// or your custom @Qualifier annotation
default Integer myCustomTransformation(String obj) {
return Formatter.toSquare(Formatter.toInteger(obj));
}
}
然后toInteger
转换的方法。如果您的toSquare
中有签名为Integer squaredString(String obj)
的方法。
e.g。
Formatter
然后你可以在你的映射器中执行此操作:
@Qualifier
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.CLASS)
public @interface SquaredString {}
public class Formatter {
@SquaredString// you can also use @Named, this is just as an example
public static Integer squaredString(String obj) {
return toSquare(toInteger(obj));
}
//your other methods are here as well
}
以上示例仅适用于自@Mapper(uses = { Formatter.class })
public interface MyMapper {
@Mapping(source = "mySourceField", target = "myTargetField", qualifiedBy = SquaredString.class)
TypeDest toSiteCatTag(TypeSrc obj);
}
/ qualifedByName
使用以来的特定映射。如果您希望采用不同的方式将qualified
转换为String
,则可以在Mapper中或Integer
中的某些类中使用签名{{}定义方法1}}。然后,MapStruct会将Mapper#uses
到Integer convertString(String obj)
的转换委托给此方法。