Property Converters

虽然 type-based conversion已经提供了一些方法来影响目标存储中某些类型转换和表示,但是当仅考虑某个类型中的特定值或属性时,它有其局限性。基于属性的转换程序允许以按属性为基础的方式配置转换规则,无论是以声明方式(通过 @ValueConverter)还是以编程方式(通过用特定的属性注册 PropertyValueConverter)。 PropertyValueConverter 可将给定值转换为其存储表示(写)并转换回来(读),如下列表所示。附加的 ValueConversionContext 提供附加信息,如映射元数据以及直接的 readwrite 方法。 .A simple PropertyValueConverter

class ReversingValueConverter implements PropertyValueConverter<String, String, ValueConversionContext> {

  @Override
  public String read(String value, ValueConversionContext context) {
    return reverse(value);
  }

  @Override
  public String write(String value, ValueConversionContext context) {
    return reverse(value);
  }
}

可以通过委托给 PropertyValueConversionsCustomConversions#getPropertyValueConverter(…) 获得 PropertyValueConverter 实例,通常通过使用 PropertyValueConverterFactory 来提供实际转换器。根据应用程序的需求,可以链接或装饰 PropertyValueConverterFactory 的多个实例——例如,应用缓存。默认情况下,Spring Data Mongo DB 使用一种缓存实现,该实现可服务于具有默认构造函数或枚举值的类型。可通过 PropertyValueConverterFactory 中的工厂方法获得一组预定义的工厂。可以使用 PropertyValueConverterFactory.beanFactoryAware(…)ApplicationContext 获取 PropertyValueConverter 实例。 可以通过 ConverterConfiguration 更改默认行为。

Declarative Value Converter

PropertyValueConverter 最直接的用法是使用 @ValueConverter 注释注释属性,该注释定义转换器类型:

Example 1. Declarative PropertyValueConverter
class Person {

  @ValueConverter(ReversingValueConverter.class)
  String ssn;
}

Programmatic Value Converter Registration

以编程方式注册使用 PropertyValueConverterRegistrar 为实体模型中的属性注册 PropertyValueConverter 实例,如下例所示。声明性注册和以编程方式注册之间的区别在于,以编程方式注册完全发生在实体模型之外。如果无法或不想对实体模型进行注释,则这种方法非常有用。

Example 2. Programmatic PropertyValueConverter registration
PropertyValueConverterRegistrar registrar = new PropertyValueConverterRegistrar();

registrar.registerConverter(Address.class, "street", new PropertyValueConverter() { … }); 1

// type safe registration
registrar.registerConverter(Person.class, Person::getSsn())                               2
  .writing(value -> encrypt(value))
  .reading(value -> decrypt(value));
1 11. 为通过其名称标识的字段注册一个转换器。
2 12. 允许注册转换器及其转换函数的类型安全变体。此方法使用类代理来确定属性。确保类和访问器都不是`final`,否则此方法将不起作用。

在注册转换器时,支持点表示法(如 registerConverter(Person.class, "address.street", …))用于在属性中导航到子文档。

MongoValueConverter 提供了一个使用 MongoConversionContext 的预类型 PropertyValueConverter 接口。

MongoCustomConversions configuration

默认情况下,MongoCustomConversions 可以处理声明性值转换器,具体取决于已配置的 PropertyValueConverterFactoryMongoConverterConfigurationAdapter 有助于设置以编程方式的值转换或定义要使用的 PropertyValueConverterFactory

Example 3. Configuration Sample
MongoCustomConversions.create(configurationAdapter -> {

    SimplePropertyValueConversions valueConversions = new SimplePropertyValueConversions();
    valueConversions.setConverterFactory(…);
    valueConversions.setValueConverterRegistry(new PropertyValueConverterRegistrar()
        .registerConverter(…)
        .buildRegistry());

    configurationAdapter.setPropertyValueConversions(valueConversions);
});