Java 要在MapStruct中使用的自定义setter

Java 要在MapStruct中使用的自定义setter,java,domain-driven-design,mapstruct,Java,Domain Driven Design,Mapstruct,我一直在看这本书,但没有成功 我正在实现域类和DTO类之间的映射;使用MapStruct。在我的领域中,我不想在我的字段中使用setter,因为我们知道现在的setter是不好的(原因很多,但这不是我问题的主题) 但是,当我想将ItemDto转换为Item时,我收到了以下消息: Error:(17, 21) java: Property "name" has no write accessor in my.example.Item. 但是,我的类Item有一个业务方法void changeNa

我一直在看这本书,但没有成功

我正在实现域类和DTO类之间的映射;使用MapStruct。在我的领域中,我不想在我的字段中使用setter,因为我们知道现在的setter是不好的(原因很多,但这不是我问题的主题)

但是,当我想将
ItemDto
转换为
Item
时,我收到了以下消息:

Error:(17, 21) java: Property "name" has no write accessor in my.example.Item.
但是,我的类
Item
有一个业务方法
void changeName(String newName)
,我想在映射器中使用它

我的映射器的代码是:

@Mapper
public interface MyMapper {

    @Mapping(source="nameDto", target = "name")
    Item map(ItemDto dto);
}
我的问题很简单:如何指定StructMap使用
changeName
作为写访问器


谢谢您的帮助。

为了实现类似的功能,您必须编写自己的自定义
accessornamigstrategy

如果您的域对象遵循相同的模式
changeXXX
,那么一个简单的实现可以如下所示:

public class CustomAccessorNamingStrategy extends DefaultAccessorNamingStrategy {


    @Override
    public boolean isSetterMethod(ExecutableElement method) {
        String methodName = method.getSimpleName().toString();
        return methodName.startsWith( "change" ) && methodName.length() > 6;
    }

    @Override
    public String getPropertyName(ExecutableElement getterOrSetterMethod) {
        String methodName = getterOrSetterMethod.getSimpleName().toString();
        if ( methodName.startsWith( "change") {
            return IntrospectorUtils.decapitalize( methodName.substring( 6 );
        }
        return super.getPropertyName( getterOrSetterMethod );
    }
}

当然,您可以调整
CustomAccessorNamingStrategy
以满足您的需要。请记住,这将用于所有对象。也可以将
项数据发送到


有关它的更多信息可以在MapStruct文档中找到。

此解决方案可以工作,但在我看来并不可靠。它映射到setter方法的名称上,每当我重构setter方法时,我的编译器都不会注意到这一点。无论如何,非常感谢你的回答,我接受了,即使我不打算实现它。你说编译器不会注意到这一点是什么意思?它基于代码中可能存在的特定模式。如果忘记映射某些内容,或者在
Mapping#target