仅为ModelMapper设置一次转换器

时间:2017-06-29 06:20:00

标签: java spring

我有以下代码,用于将类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则不再创建它。这不是一个好的解决方案,因为如果您对此方法进行了数千次调用,则会增加不必要的开销。

有什么好的解决方案吗?

1 个答案:

答案 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和转换器,而是要在两个类之间进行映射。