我有以下代码,用于将类iptables -t raw -A OUTPUT -p tcp ! --destination-ports 80,443
的对象转换为其User
类型的DTO:
GetUserDto
它第一次正常工作,但随后对public GetUserDto convertToDto(User user) {
Converter<User, GetUserDto> converter = context -> {
User source = context.getSource();
GetUserDto target = new GetUserDto();
target.setDescription(source.getDescription());
target.setId(source.getId());
target.setName(source.getName());
target.setImageId(source.getImageId());
return target;
};
modelMapper.createTypeMap(User.class, GetUserDto.class).setConverter(converter);
return modelMapper.map(user, GetUserDto.class);
}
的调用抛出:
convertToDto
我发现了其他一些与此有关的帖子,其中一个建议对java.lang.IllegalStateException: A TypeMap already exists for class com.boot.cut_costs.model.User and class com.boot.cut_costs.dto.user.ExtendedGetUserDto
TypeMap
进行无效检查,如果不是modelMapper
则不再创建它。这不是一个好的解决方案,因为如果您对此方法进行了数千次调用,则会增加不必要的开销。
有什么好的解决方案吗?
答案 0 :(得分:1)
我发现了一些关于此事的其他帖子,一个建议无效检查 ModelMapper的TypeMap,如果它不是null,则不再创建它。 这不是一个好的解决方案,好像你有成千上万的电话 它为它增加了不必要的开销。
如果您查看org.modelmapper.ModelMapper.getTypeMap()
的代码
和org.modelmapper.ModelMapper.createTypeMap()
,你会看到
只需调用一个方法来检索TypeMap
,就可以创建一个更高开销的TypeMap
。
如果对象存在,则从地图返回对象是直的:
public <S, D> TypeMap<S, D> getTypeMap(Class<S> sourceType, Class<D> destinationType) {
Assert.notNull(sourceType, "sourceType");
Assert.notNull(destinationType, "destinationType");
return config.typeMapStore.<S, D>get(sourceType, destinationType, null);
}
虽然添加会执行更多的事情
它创建一个代理类型,执行同步任务并在创建TypeMap
实例之前进行一些检查,最后将它放在地图中:
private <S, D> TypeMap<S, D> createTypeMapInternal(S source, Class<S> sourceType,
Class<D> destinationType, String typeMapName, Configuration configuration) {
if (source != null)
sourceType = Types.<S>deProxy(source.getClass());
Assert.state(config.typeMapStore.get(sourceType, destinationType, typeMapName) == null,
String.format("A TypeMap already exists for %s and %s", sourceType, destinationType));
return config.typeMapStore.create(source, sourceType, destinationType, typeMapName,
(InheritingConfiguration) configuration, engine);
}
也会调用:
public <S, D> TypeMap<S, D> create(S source, Class<S> sourceType, Class<D> destinationType,
String typeMapName, InheritingConfiguration configuration, MappingEngineImpl engine) {
synchronized (lock) {
TypeMapImpl<S, D> typeMap = new TypeMapImpl<S, D>(sourceType, destinationType, typeMapName,
configuration, engine);
if (configuration.isImplicitMappingEnabled()
&& ImplicitMappingBuilder.isMatchable(typeMap.getSourceType())
&& ImplicitMappingBuilder.isMatchable(typeMap.getDestinationType()))
new ImplicitMappingBuilder<S, D>(source, typeMap, config.typeMapStore,
config.converterStore).build();
typeMaps.put(TypePair.of(sourceType, destinationType, typeMapName), typeMap);
return typeMap;
}
}
检查是否有更有效的解决方案:
if (modelMapper.getTypeMap(User.class,GetUserDto.class) == null){
modelMapper.createTypeMap(User.class, GetUserDto.class).setConverter(converter);
}
return modelMapper.map(user, GetUserDto.class);
现在,如果您真的想要避免不必要的处理,可以创建TypeMap并将所有与转换器关联的转换器设置为一次。
public void initTypeMaps(){
modelMapper.createTypeMap(User.class, GetUserDto.class).setConverter(converterUserAndUserDto);
modelMapper.createTypeMap(Other.class, GetOtherDto.class).setConverter(converterOtherAndOtherDto);
...
}
最后,如果您在短时间内对此方法进行了数千次调用,并且希望将开销减少到最大值,请不要使用ModelMapper和转换器,而是要在两个类之间进行映射。