无需额外样板代码,能否自动装配KSP生成的Konvert映射器?
批量注册Konvert生成的映射器为Spring Bean
问题场景
基于KSP的Konvert框架定义DTO/领域模型映射接口:
@Konverter interface SimpleNoteMapper { fun toDto(note: SimpleNote): SimpleNoteDto fun toDomain(note: SimpleNoteDto): SimpleNote }
框架自动生成的实现为object单例类:
public object SimpleNoteMapperImpl : SimpleNoteMapper { @GeneratedKonverter(priority = 5_000) override fun toDto(note: SimpleNote): SimpleNoteDto = SimpleNoteDto( id = note.id, name = note.name ) @GeneratedKonverter(priority = 5_000) override fun toDomain(note: SimpleNoteDto): SimpleNote = SimpleNote( id = note.id, name = note.name ) }
使用@Autowired注入接口时,Spring提示找不到对应Bean:
Field simpleNoteMapper in com.project.example.simplenotes.api.controller.SimpleNotesController required a bean of type 'com.project.example.simplenotes.api.mapper.SimpleNoteMapper' that could not be found. The injection point has the following annotations: - @org.springframework.beans.factory.annotation.Autowired(required=true) Action: Consider defining a bean of type 'com.project.example.simplenotes.api.mapper.SimpleNoteMapper' in your configuration.
手动编写配置类注册Bean可解决问题,但需批量处理所有映射器,避免重复编写配置。
解决方案
方案1:组件扫描+自定义注解过滤器
利用生成类自带的@GeneratedKonverter注解,通过自定义过滤器让Spring自动扫描注册:
- 定义注解过滤器类:
class GeneratedKonverterFilter : TypeFilter { override fun match(metadata: MetadataReader, context: MetadataReaderFactory): Boolean { return metadata.annotationMetadata.hasAnnotation(GeneratedKonverter::class.qualifiedName) } }
- 添加全局扫描配置:
@Configuration @ComponentScan( basePackages = ["com.project.example.simplenotes.api.mapper"], // 映射器所在包路径 includeFilters = [ComponentScan.Filter(type = FilterType.CUSTOM, classes = [GeneratedKonverterFilter::class])] ) class MapperAutoConfiguration
方案2:BeanDefinitionRegistryPostProcessor批量注册
通过Spring扩展接口,在容器初始化阶段批量扫描注册所有生成类:
@Configuration class KonvertMapperBeanRegistrar : BeanDefinitionRegistryPostProcessor { override fun postProcessBeanDefinitionRegistry(registry: BeanDefinitionRegistry) { val scanner = ClassPathBeanDefinitionScanner(registry) scanner.addIncludeFilter(AnnotationTypeFilter(GeneratedKonverter::class.java)) scanner.scan("com.project.example.simplenotes.api.mapper") // 映射器所在包路径 } override fun postProcessBeanFactory(beanFactory: ConfigurableListableBeanFactory) {} }
方案3:检查Konvert原生Spring集成
部分映射框架会提供Spring集成扩展,可查看Konvert官方文档,确认是否存在@EnableKonvert这类注解,添加到配置类后即可自动完成所有映射器的Bean注册。
验证
配置完成后,直接注入接口即可正常使用:
@RestController class SimpleNotesController { @Autowired lateinit var simpleNoteMapper: SimpleNoteMapper // 业务逻辑代码 }
内容的提问来源于stack exchange,提问作者JustAnEuropean
相关产品推荐
相关产品推荐

