MapStruct Plus 是 MapStruct 的增強工具,在 Mapstruct 的基礎上,實現了自動生成 Mapper 介面的功能,並強化了部分功能,使 Java 型別轉換更加便捷、優雅。
MapStructPlus官網
此次迎來了一次較大版本的更新,更新日誌如下:
- 最佳化複雜物件轉換邏輯,佔用元空間更小!效能更快!
此版本針對於複雜物件的自動轉換邏輯,進行了最佳化和部分的重新設計,減少了一些不必要的轉換方法,佔用元空間更小。
以 RuoYi-Vue-Plus 為例,使用新版本後,元空間佔用減少了 7MB,根據專案的複雜程度不同,減少的記憶體佔用也有所不同。
且根據 issue#67 中提到,在 SpringBoot + Aop 場景下,效能會受影響, 在新版本中,修改了實現方式,效能比提升一半以上。
- 去除 hutool 等依賴,目前專案中只依賴了 MapStruct
從 1.4.0 版本之後,去除了 MapStruct 之外的依賴,打包後體積更小。
但當需要使用 Map
與物件轉換時,需要額外引入 hutool-core
依賴包。
- 適配物件迴圈巢狀場景
類迴圈巢狀是指兩個類互相引用,例如,源物件和目標物件結構都包含父物件和子物件之間的雙向關聯。
當存在這種情況時,直接進行轉換時,會導致棧溢位的問題(stack overflow error)。
示例:
@Data
public class TreeNode {
private TreeNode parent;
private List<TreeNode> children;
}
@Data
public class TreeNodeDto {
private TreeNodeDto parent;
private List<TreeNodeDto> children;
}
parent
屬性可以是其他型別的,可能跨越一個更長的屬性鍊形成的巢狀迴圈。
為了適配這種情況,MapStructPlus 的 AutoMapper
註解中增加了 cycleAvoiding
屬性,該屬性用於標識,是否需要避免迴圈巢狀的問題。
預設為 false
,如果需要避免迴圈巢狀,需要將該屬性設定為 true
。
當配置為 true
時,在整個物件的轉換過程鏈路中,會傳遞一個 CycleAvoidingMappingContext
物件,臨時儲存轉換生成的物件,
在轉換鏈路中,如果發現需要生成的物件已經存在,會直接返回該型別,從而避免棧溢位問題。
以上面的示例為例,在 AutoMapper
註解中,配置 cycleAvoiding
屬性為 true
,如下所示:
@Data
@AutoMapper(target = TreeNodeDto.class, cycleAvoiding = true)
public class TreeNode {
private TreeNode parent;
private List<TreeNode> children;
}
@Data
@AutoMapper(target = TreeNode.class, cycleAvoiding = true)
public class TreeNodeDto {
private TreeNodeDto parent;
private List<TreeNodeDto> children;
}
編譯生成的轉換邏輯如下:
public TreeNodeDto convert(TreeNode arg0, CycleAvoidingMappingContext arg1) {
TreeNodeDto target = arg1.getMappedInstance(arg0, TreeNodeDto.class);
if (target != null) {
return target;
}
if (arg0 == null) {
return null;
}
TreeNodeDto treeNodeDto = new TreeNodeDto();
arg1.storeMappedInstance(arg0, treeNodeDto);
treeNodeDto.setParent(demoConvertMapperAdapterForCycleAvoiding.iglm_TreeNodeToTreeNodeDto(arg0.getParent(), arg1));
treeNodeDto.setChildren(
demoConvertMapperAdapterForCycleAvoiding.iglm_TreeNodeToTreeNodeDto(arg0.getChildren(), arg1));
return treeNodeDto;
}
AutoMapping
、ReverseAutoMapping
支援qualifiedByName
、conditionQualifiedByName
和dependsOn
屬性AutoMappings
支援配置在方法上面