Quarkus依赖注入问题:无法依据UriInfo存在性选择实现类
Quarkus依赖注入场景适配问题
我用Quarkus 2.16.3 + Kotlin搭建了如下代码结构:
interface Resolver { fun getInfo(): String } @ApplicationScoped @Default @Priority(1) class ResolverNoRequest(): Resolver { override fun getInfo(): String { return "myInfo" } } @RequestScoped @Alternative @Priority(2) class ResolverWithRequest(val uriInfo: UriInfo) : Resolver { override fun getInfo(): String { val hostname = uriInfo.baseUri.host return "myInfo with $hostname" } }
注入Resolver的Consumer类:
@ApplicationScoped class Consumer(val resolver: Resolver){ fun process(){ println(resolver.getInfo()) } }
预期效果
- 请求上下文(如REST端点调用)时,注入
ResolverWithRequest - 无请求上下文(如批处理任务)时,注入
ResolverNoRequest
当前问题
多次调整注解、改用Instance<Resolver>都无法实现按上下文切换注入的逻辑。无请求上下文时,系统仍尝试注入ResolverWithRequest,因缺少UriInfo抛出错误:java.lang.IllegalStateException: No RESTEasy Reactive request in progress。目前只能用Instance<Resolver>配合try-catch的方式规避,不够优雅,希望找到Quarkus原生的正确用法。
解决方案:使用@ConditionalOnRequest注解
Quarkus提供了@ConditionalOnRequest注解,可让bean仅在请求上下文存在时生效。修改ResolverWithRequest的注解配置:
@RequestScoped @Alternative @Priority(2) @ConditionalOnRequest class ResolverWithRequest(val uriInfo: UriInfo) : Resolver { override fun getInfo(): String { val hostname = uriInfo.baseUri.host return "myInfo with $hostname" } }
调整后,当无请求上下文时,ResolverWithRequest会被CDI忽略,自动选择ResolverNoRequest作为默认实现;在请求上下文内,由于ResolverWithRequest优先级更高,会被优先注入。Consumer类无需修改,保持原有注入方式即可。
备选方案:通过Instance筛选可用bean
如果无法使用@ConditionalOnRequest,可通过Instance遍历并筛选符合当前上下文的bean:
@ApplicationScoped class Consumer(@Any private val resolvers: Instance<Resolver>) { fun process() { val resolver = resolvers.stream() .filter { bean -> // 请求作用域bean仅在请求上下文激活时可用 bean.javaClass.getAnnotation(RequestScoped::class.java)?.let { RequestContext.current().isActive } ?: true } .max(Comparator.comparingInt { bean -> // 按优先级排序选择最高优先级的可用bean bean.javaClass.getAnnotation(Priority::class.java)?.value ?: 0 }) .orElseThrow { IllegalStateException("未找到可用的Resolver实现") } println(resolver.getInfo()) } }
内容的提问来源于stack exchange,提问作者olivierbeltrandocintoo
相关产品推荐
相关产品推荐

