如何向PropertyValueConverter注入运行时配置参数?
运行时配置注入与字段级定制的PropertyValueConverter实现方案
1. 自定义注解实现字段级字节长度配置
先定义一个运行时注解,用来为每个字段单独指定字节长度限制:
@Target(AnnotationTarget.PROPERTY) @Retention(AnnotationRetention.RUNTIME) annotation class StreamByteLimit(val value: Int)
在实体字段上同时标记该注解与转换器:
@Field(type = FieldType.Text) @ValueConverter(CompactingInputStreamProviderConverter::class) @StreamByteLimit(1048576) // 1MB字节限制 var fullText: (() -> InputStream)?
2. 将转换器声明为Spring Bean并注入配置
把转换器定义为Spring组件,通过依赖注入获取全局配置,同时利用PropertyValueConverterContext获取字段注解信息:
@Component class CompactingInputStreamProviderConverter( // 注入全局配置Bean,提供默认字节限制 private val streamConfig: StreamConfig ) : PropertyValueConverter { override fun convertFromDatabaseValue(value: Any?, context: PropertyValueConverterContext): Any? { // 获取当前字段的元数据 val persistentProperty = context.persistentProperty // 读取字段上的StreamByteLimit注解 val limitAnnotation = persistentProperty.findAnnotation(StreamByteLimit::class.java) // 优先级:字段注解配置 > 全局默认配置 val byteLimit = limitAnnotation?.value ?: streamConfig.defaultByteLimit // 实现字节长度限制逻辑 if (value is InputStream) { return { LimitedInputStream(value, byteLimit) } } return null } override fun convertToDatabaseValue(value: Any?, context: PropertyValueConverterContext): Any? { // 处理存入数据库的流限制逻辑 val inputStreamProvider = value as (() -> InputStream)? ?: return null val persistentProperty = context.persistentProperty val limitAnnotation = persistentProperty.findAnnotation(StreamByteLimit::class.java) val byteLimit = limitAnnotation?.value ?: streamConfig.defaultByteLimit return LimitedInputStream(inputStreamProvider.invoke(), byteLimit) } }
3. 核心逻辑说明
- 字段信息获取:通过
PropertyValueConverterContext提供的persistentProperty,可以拿到字段的所有注解、类型等元数据,实现字段级的定制化配置。 - 运行时配置注入:转换器作为Spring Bean后,可直接注入任何Spring管理的配置类、工具类,灵活获取运行时动态配置。
- 配置优先级:字段注解的配置优先级高于全局默认配置,既支持全局统一设置,也允许单个字段特殊定制。
内容的提问来源于stack exchange,提问作者Steve P
相关产品推荐
相关产品推荐

