You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Mapstruct如何配置全局规则实现源字段映射到带__c后缀的目标字段

MapStruct自动映射源字段到加__c后缀目标字段的解决方案

方案1:编译期全局命名策略(推荐,性能无损耗)

该方案通过自定义MapStruct的访问器命名策略,在编译阶段自动识别带__c后缀的目标字段,匹配对应同源字段,无运行期反射开销,适合项目中普遍存在「目标字段=源字段+__c」映射规则的场景。

第一步:自定义命名策略类

import org.mapstruct.ap.spi.DefaultAccessorNamingStrategy;
import javax.lang.model.element.ExecutableElement;

public class SuffixAccessorNamingStrategy extends DefaultAccessorNamingStrategy {
    private static final String TARGET_SUFFIX = "__c";

    @Override
    public String getPropertyName(ExecutableElement getterOrSetterMethod) {
        String propertyName = super.getPropertyName(getterOrSetterMethod);
        // 目标类带__c后缀的字段自动去除后缀后,和源字段做匹配
        if (propertyName.endsWith(TARGET_SUFFIX)) {
            return propertyName.substring(0, propertyName.length() - TARGET_SUFFIX.length());
        }
        return propertyName;
    }
}

第二步:注册自定义策略

在项目resources目录下创建层级路径META-INF/services/,新建文件名为org.mapstruct.ap.spi.AccessorNamingStrategy,文件内容填写你自定义策略类的全限定名即可,示例:

com.yourbusiness.config.SuffixAccessorNamingStrategy

配置完成后所有Mapper的目标字段只要符合「源字段名+__c」的规则,都不需要单独写@Mapping注解,编译时会自动完成映射匹配,存在特殊规则的字段单独加@Mapping注解即可覆盖自动匹配逻辑。

方案2:单Mapper局部生效(不需要全局配置)

如果只需要在个别Mapper中使用该规则,不需要全局生效,可以自定义映射方法实现批量转换:

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Named;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import java.beans.PropertyDescriptor;

@Mapper
public interface ContactMapper {
    ContactMapper INSTANCE = Mappers.getMapper(ContactMapper.class);

    @Mapping(target = ".", source = ".", qualifiedByName = "suffixFieldMapping")
    SimpleDestination customerContact(SimpleSource source);

    @Named("suffixFieldMapping")
    default SimpleDestination mapWithSuffix(SimpleSource source) throws Exception {
        if (source == null) {
            return null;
        }
        SimpleDestination target = new SimpleDestination();
        BeanWrapper srcWrapper = new BeanWrapperImpl(source);
        BeanWrapper targetWrapper = new BeanWrapperImpl(target);

        for (PropertyDescriptor pd : srcWrapper.getPropertyDescriptors()) {
            String fieldName = pd.getName();
            if ("class".equals(fieldName) || pd.getReadMethod() == null) {
                continue;
            }
            String targetField = fieldName + "__c";
            if (targetWrapper.isWritableProperty(targetField)) {
                targetWrapper.setPropertyValue(targetField, pd.getReadMethod().invoke(source));
            }
        }
        return target;
    }
}

注意事项

  • 方案1依赖MapStruct的SPI机制,需要保证自定义策略类在编译期的annotationProcessor路径中可被加载
  • 两种方案都支持和单独配置的@Mapping注解共存,手动配置的注解优先级高于自动匹配规则

内容的提问来源于stack exchange,提问作者ibo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 13:24:09