MapStruct:如何使用可选参数执行@AfterMapping?

MapStruct: How to do an @AfterMapping with optional parameters?

我创建了一个抽象映射器 class,它具有以下方法:

public abstract Dest mapSourceToDest(Source source);
public abstract Dest mapSourceToDestWithParams(Source source, @Context Param1 param1; @Context Param2 param2);

Source 中有两个成员,在转换为 Dest 时转换成本非常高(就性能而言)。
source的所有成员都需要进行转换(包括两次昂贵的转换)时应该使用上述第一种方法。
结果应该使用第二种方法在完成从 sourcedest 的转换之前,已经知道两个 "expensive" 成员的转换。在本例中,这两个成员的转换结果作为参数 param1param2 传递。这些参数应该用于避免昂贵的转换。
两个成员的转换是在一个用@AfterMapping注释的方法中完成的。我基本上想在 AfterMapping 方法中执行以下操作:

基本上应该是这样的:

@AfterMapping
protected void setExpensiveParams(Source source, @MappingTarget Dest dest, 
                                   @Context Param1 param1, @Context Param2 param2) {
    if (param1 == null || param2 == null) {
        performExpensiveConversionForParam1AndParam2();
    } else {
       dest.setParam1(param1);
       dest.setParam2(param2); 
    } 
}

这在这两种情况下都不起作用,因为此 AfterMapping 方法仅在提供带有 @Context 注释的两个参数时才会被调用。这是预期的,因为 MapStruct 文档清楚地指出像这样的上下文参数可能不为空。

我想不出一种方法来执行这两种替代类型的 AfterMapping,这取决于一个映射器中可选参数的存在 class。我现在的解决方法是使用两个映射器 classes。不过,我真的很想用一个映射器 class 来处理这个问题。

我看到了 2 个选项。

选项 1: * 您可以使用属性 Param1 和 Param2 创建自己的上下文 class,您可以使用 Param1 和 Param2(优化)或不使用这些属性来构造它们。此上下文仅传递给一个方法。 MapStruct 的一个鲜为人知的特性是您可以将生命周期方法 ( @AfterMapping ) 放在上下文中的方法中。根据是否设置了参数,您可以从映射器的上下文中调用昂贵的映射或在上下文中实现它们

选项 2: 使用 @MappingTarget 并使用已经设置的两个目标参数预先创建目标对象。使相应的来源无效。使用 nullvaluepropertymappingstrategy .ignore 以便 MapStruct 在相应的源属性为空时跳过这些。您甚至可以使用第二个方法的签名在默认方法中实现它。