2017-06-02 554 views
1

以下是我的上下文:我使用byteBuddy動態生成一個類,該對象基於外部配置將對象轉換爲另一個對象。我遇到了一些問題,我想找到一個替代方案,就是我發現MapStruct的方式。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

在編譯期間你有'TypeDest'和'TypeSrc'還是他們是動態類?你是否在運行時生成它們? – Filip

回答

2

如果您的兩種類型TypeDestTypeSrc不是在運行時生成的,即它們是您的編譯類,那麼您可以實現您想要的。 MapStruct在運行時不起作用,因爲它是一個Annotation Processor並生成Java代碼。如果存在一些問題,比如你試圖映射不存在的字段或者存在不明確的映射方法,那麼你會得到編譯時錯誤。

它看起來是這樣的:

@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改造。如果您有Formatter中的簽名Integer squaredString(String obj)的方法。

例如

@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轉換爲Integer的方法不同,則可以在Mapper中或Mapper#uses中的某些類中定義一種方法,其簽名爲Integer convertString(String obj)。 MapStruct然後將從StringInteger的轉換委託給此方法。

有關映射方法解析的更多信息,您可以在參考文檔中找到更多關於映射與限定符herehere的信息。

+0

看起來很完美。非常感謝,你爲我節省了很多時間:) – nbchn