基于Kotlin协程的Spring EL表达式求值失败问题求助
问题解决:@ConditionalOnExpression无法引用Bean的问题
问题根源
@ConditionalOnExpression的评估时机处于Spring容器初始化的早期阶段——此时Bean定义刚被加载,还未完成实例化和依赖注入,因此EL表达式根本无法找到myBean实例,哪怕移除suspend修饰符也无法解决,核心矛盾是Bean尚未创建。
解决方案:自定义Condition实现
直接实现Spring的Condition接口,在其中手动获取Bean实例并执行判断逻辑,绕过EL表达式的时机限制。
步骤1:编写自定义Condition类
import org.springframework.context.annotation.Condition import org.springframework.context.annotation.ConditionContext import org.springframework.core.type.AnnotatedTypeMetadata import kotlinx.coroutines.runBlocking class MyBeanEnabledCondition : Condition { override fun matches(context: ConditionContext, metadata: AnnotatedTypeMetadata): Boolean { val beanFactory = context.beanFactory ?: return false // 使用BeanProvider避免强制实例化可能引发的依赖问题 val myBeanProvider = beanFactory.getBeanProvider(MyBean::class.java) return runBlocking { // 若Bean存在则执行判断,否则返回false myBeanProvider.getIfAvailable()?.isEnabled("test") ?: false } } }
注:如果已经移除
suspend修饰符,可以去掉runBlocking,直接调用isEnabled方法。
步骤2:在配置类上使用自定义Condition
@Configuration @Conditional(MyBeanEnabledCondition::class) class MyConfig {}
补充说明
如果你的判断逻辑可以简化为配置属性判断,也可以用@ConditionalOnProperty替代,更简洁:
@Configuration @ConditionalOnProperty(name = "my.feature.enabled", havingValue = "true") class MyConfig {}
这种方式无需自定义Condition,适合简单的开关场景。
内容的提问来源于stack exchange,提问作者Hantsy
相关产品推荐
相关产品推荐

