如何在不破坏自动配置的情况下,在Spring Boot中自定义MappingMongoConverter(设置MapKeyDotReplacement)?

23
我该如何在不改变Spring-Data自动配置的任何mongo-stuff的情况下,定制MappingMongoConverter以适应我的Spring Boot应用程序(1.3.2.RELEASE)?
我的当前解决方案是:
@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有更简单的方法吗?

4个回答

14

还有一个简短的版本:

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

记得将它放入Spring将知晓的类中 - 例如带有@Configuration注释的类。


谢谢,它起作用了。需要研究MappingMongoConverter。 - Lakshman Miani
真的不知道你可以使用Bean作为参数自动装配方法。太疯狂了!而且它还起作用了! - David
我今天尝试了这个解决方案,效果非常完美。它解决了我遇到的异常问题,并且以一种非常优雅的方式完成。非常感谢你提供这个解决方案。 - Pmsmm

13

这是正确的方式。自动配置的 MappingMongoConverter 使用 @ConditionalOnMissingBean(MongoConverter.class) 注释,因此添加自己的 MappingMongoConverter bean 将导致自动配置退回到您的自定义转换器。

一个小修正:您不需要调用 mongoConverter.afterPropertiesSet()。容器会替您调用它。


11

我在最新版Spring Boot中遇到了这个问题。你的方法对我或被接受的答案都没有用......我的引导应用程序似乎忽略了我的自定义映射转换器。

所以我在配置类中自动装配了Boot使用的MappingMongoConverter,然后在其上设置了setMapKeyDotReplacement。

@Autowired
private MappingMongoConverter mongoConverter;

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

1
由于您没有将依赖项(mongoConverter)指定为可选项,因此无需进行空值检查。 - LoganMzz
1
对我来说,解决方案在将方法重命名为“mappingMongoConverter”后开始工作,因为我正在扩展“AbstractMongoConfiguration”。 - heroin

0
我们可以在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);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接