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