属性转换器
尽管 基于类型的转换 已提供影响目标存储中特定类型转换和表示的方法,但当仅考虑特定类型的特定值或属性进行转换时,它存在局限性。基于属性的转换器允许按属性逐个配置转换规则,无论是声明式(通过 @ValueConverter
)还是以编程方式(通过为特定属性注册 PropertyValueConverter
)。
PropertyValueConverter
可以将给定值转换为其存储表示(写入)并返回(读取),如下表所示。附加的 ValueConversionContext
提供附加信息,例如映射元数据以及直接 read
和 write
方法。
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);
}
}
你可以通过委托给 PropertyValueConversions 来从 CustomConversions#getPropertyValueConverter(…) 获取 PropertyValueConverter 实例,通常通过使用 PropertyValueConverterFactory 来提供实际转换器。根据你的应用程序的需求,你可以链接或装饰 PropertyValueConverterFactory 的多个实例——例如,应用缓存。默认情况下,Spring Data MongoDB 使用一个缓存实现,它可以服务具有默认构造函数或枚举值的数据类型。一组预定义的工厂通过 PropertyValueConverterFactory 中的工厂方法提供。你可以使用 PropertyValueConverterFactory.beanFactoryAware(…) 从 ApplicationContext 获取 PropertyValueConverter 实例。
你可以通过 ConverterConfiguration 更改默认行为。
声明式值转换器
PropertyValueConverter 最直接的用法是使用 @ValueConverter 注解来注释属性,该注解定义转换器类型
class Person {
@ValueConverter(ReversingValueConverter.class)
String ssn;
}
编程式值转换器注册
编程式注册使用 PropertyValueConverterRegistrar 为实体模型中的属性注册 PropertyValueConverter 实例,如下面的示例所示。声明式注册和编程式注册之间的区别在于,编程式注册完全发生在实体模型之外。如果你无法或不想注释实体模型,则这种方法很有用。
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 | 为由其名称标识的字段注册一个转换器。 |
2 | 类型安全变体,允许注册一个转换器及其转换函数。此方法使用类代理来确定属性。确保类和访问器都不是 final,否则此方法不起作用。 |
在注册转换器时,不支持点表示法(例如 registerConverter(Person.class, "address.street", …))用于在属性之间导航到子文档。 |
MongoValueConverter 提供了一个预类型的 PropertyValueConverter 接口,它使用 MongoConversionContext。 |
MongoCustomConversions 配置
默认情况下,MongoCustomConversions
可以处理声明式值转换器,具体取决于配置的 PropertyValueConverterFactory
。MongoConverterConfigurationAdapter
有助于设置编程值转换或定义要使用的 PropertyValueConverterFactory
。
MongoCustomConversions.create(configurationAdapter -> {
SimplePropertyValueConversions valueConversions = new SimplePropertyValueConversions();
valueConversions.setConverterFactory(…);
valueConversions.setValueConverterRegistry(new PropertyValueConverterRegistrar()
.registerConverter(…)
.buildRegistry());
configurationAdapter.setPropertyValueConversions(valueConversions);
});