
本文介绍如何在共享单例 modelmapper 实例的前提下,针对同一对源类(user)和目标类(userdto)配置多个独立映射规则——例如默认全字段映射,以及跳过特定字段(如 address)的精简映射。
本文介绍如何在共享单例 modelmapper 实例的前提下,针对同一对源类(user)和目标类(userdto)配置多个独立映射规则——例如默认全字段映射,以及跳过特定字段(如 address)的精简映射。
在实际项目中,我们常需对同一组 Java 类(如 User → UserDto)提供多种映射行为:一种是完整映射(含嵌套对象),另一种则需排除敏感或冗余字段(如跳过 address)。由于 ModelMapper 默认采用“类型级映射”(TypeMap),且单例实例全局复用,直接调用 map() 无法区分上下文。解决方案不是创建多个 ModelMapper 实例,而是预先注册多个命名化的 TypeMap,并通过显式指定映射配置来触发不同逻辑。
✅ 正确做法:注册多个 TypeMap 并命名区分
ModelMapper 支持为同一源-目标类型对注册多个 TypeMap,关键在于使用 createTypeMap() 并赋予唯一名称(或通过 addMappings() 配置差异化规则):
// 初始化时一次性配置(推荐放在 Configuration 或 @PostConstruct 中)
ModelMapper modelMapper = new ModelMapper();
// 1. 默认映射:全字段(包括 address)
modelMapper.createTypeMap(User.class, UserDto.class, "default");
// 2. 精简映射:跳过 address 字段
TypeMap<User, UserDto> withoutAddressMap =
modelMapper.createTypeMap(User.class, UserDto.class, "withoutAddress");
withoutAddressMap.addMappings(mapper -> mapper.skip(UserDto::setAddress));? 使用时显式指定映射配置
调用 map() 时,需传入对应的 TypeMap 实例(而非仅靠 class 参数):
User user = new User();
user.setName("Alice");
user.setAddress(new Address("123 Main St"));
// ✅ 使用默认映射(含 address)
UserDto fullDto = modelMapper.map(user, UserDto.class); // address 被复制
// ✅ 使用精简映射(跳过 address)
UserDto slimDto = modelMapper.map(user,
modelMapper.getTypeMap(User.class, UserDto.class, "withoutAddress"));⚠️ 注意:modelMapper.map(source, destinationType) 默认使用未命名的 TypeMap;若存在多个 TypeMap,必须显式通过 getTypeMap(..., name) 获取并传入,否则可能抛出 ConfigurationException(提示存在歧义映射)。
? 进阶技巧:封装为工具方法提升可读性
为避免重复获取 TypeMap,建议封装便捷方法:
public class UserMapper {
private final ModelMapper modelMapper;
public UserMapper(ModelMapper modelMapper) {
this.modelMapper = modelMapper;
}
public UserDto toDto(User user) {
return modelMapper.map(user, UserDto.class);
}
public UserDto toDtoWithoutAddress(User user) {
TypeMap<User, UserDto> typeMap =
modelMapper.getTypeMap(User.class, UserDto.class, "withoutAddress");
return modelMapper.map(user, typeMap);
}
}✅ 总结
- ModelMapper 单例完全支持同一源-目标类型对的多映射策略;
- 核心是使用 createTypeMap(..., name) 注册带名称的 TypeMap,并通过 addMappings() 定制规则(如 skip());
- 调用时必须显式传入目标 TypeMap,不可依赖默认行为;
- 推荐将映射逻辑封装为语义化方法,增强代码可维护性与可读性。
这样既保持了 ModelMapper 的轻量与高效,又满足了业务场景中灵活、可控的映射需求。

















