如何在 Spring-Boot 中自定义 MappingMongoConverter (setMapKeyDotReplacement) 而不破坏自动配置?

How to customize MappingMongoConverter (setMapKeyDotReplacement) in Spring-Boot without breaking the auto-configuration?

如何在 Spring-Boot-Application (1.3.2.RELEASE) 中自定义 MappingMongoConverter,而不更改任何自动配置的 mongo-内容通过 spring-data?

我目前的解决方案是:

@Configuration
public class MongoConfig {

  @Autowired
  private MongoDbFactory mongoFactory;

  @Autowired
  private MongoMappingContext mongoMappingContext;

  @Bean
  public MappingMongoConverter mongoConverter() throws Exception {
    DbRefResolver dbRefResolver = new DefaultDbRefResolver(mongoFactory);
    MappingMongoConverter mongoConverter = new MappingMongoConverter(dbRefResolver, mongoMappingContext);
    //this is my customization
    mongoConverter.setMapKeyDotReplacement("_");
    mongoConverter.afterPropertiesSet();
    return mongoConverter;
  }
}

这是正确的方法还是我用这个破坏了一些东西?
还是有更简单的方法来设置 mapKeyDotReplacement?

这才是正确的做法。自动配置的 MappingMongoConverter 带有 @ConditionalOnMissingBean(MongoConverter.class) 注释,因此添加您自己的 MappingMongoConverter bean 将导致自动配置后退以支持您的自定义转换器。

一个小的更正:您不需要打电话给 mongoConverter.afterPropertiesSet()。容器会为您调用它。

我在最新版本的 spring 引导中 运行 遇到了这个问题。您的方法对我或接受的答案不起作用...我的启动应用程序似乎忽略了我的自定义映射转换器。

所以我在配置中做了什么 class 我在引导使用的 MappingMongoConverter 中自动装配,然后在上面设置 setMapKeyDotReplacement。

@Autowired
private MappingMongoConverter mongoConverter;

// Converts . into a mongo friendly char
@PostConstruct
public void setUpMongoEscapeCharacterConversion() {
    mongoConverter.setMapKeyDotReplacement("_");
}

还有更短的版本:

@Autowired
void setMapKeyDotReplacement(MappingMongoConverter mappingMongoConverter) {
    mappingMongoConverter.setMapKeyDotReplacement("_");
}

记得把它放到 class 中,Spring 会知道 - 例如class 注释为 @Configuration

我们可以使用 Mongo 模板中的 默认映射转换器 更改我们需要的内容

/**
 * <p>
 * Gets default mapping converted that can be overiden based on the need.
 * This is the default mapping used inside mongo template when no custom converter is passed
 * </p>
 * @param factory
 * @return
 */
private static MongoConverter getDefaultMongoConverter(MongoDbFactory factory) {
    DbRefResolver dbRefResolver = new DefaultDbRefResolver(factory);
    MongoCustomConversions conversions = new MongoCustomConversions(Collections.emptyList());
    MongoMappingContext mappingContext = new MongoMappingContext();
    mappingContext.setSimpleTypeHolder(conversions.getSimpleTypeHolder());
    mappingContext.afterPropertiesSet();
    MappingMongoConverter converter = new MappingMongoConverter(dbRefResolver, mappingContext);
    converter.setCustomConversions(conversions);
    converter.setCodecRegistryProvider(factory);
    converter.afterPropertiesSet();
    return converter;
}


@Bean
@Primary
public MongoTemplate mongoTemplate() {
    MappingMongoConverter mappingMongoConverter = (MappingMongoConverter) getDefaultMongoConverter(mongoDbFactory());
    // custom key to map dot (.) with "__mongo_key__" when saving and replacing it with dot (.) again when it 
    // is retrieved
    mappingMongoConverter.setMapKeyDotReplacement("__mongo_key__");
    return new MongoTemplate(mongoDbFactory(), mappingMongoConverter);
}