Учитывая интерфейс и класс реализации, подобный этому.
interface MyBean{
suspend fun suspend isEnabled(name:String): Boolean
}
@Service("myBean")
@NoArg // I created an annotation and configured the noarg plugin
//to satisfy Spring EL's `noarg default constructor` requirements.
class MyMbean(val antoherBean: AnotherBean): MyBean{
override suspend fun isEnabled(name:String): Boolean{
}
}
При нанесении на @ConditonalOnExpression вот так.
@Configuration
@ConditionalOnExpression("#myBean.isEnabled('test')")
class MyConfig{}
Что касается строки EL, я пробовал #{myBean.isEnabled('test')} и т. д. Ничего не помогло.
EL1008E: Property or field 'myBean' cannot be found on object of type
'org.springframework.beans.factory.config.BeanExpressionContext'
- maybe not public or not valid?
Я использовал последнюю версию Spring Boot 3.3.1 и Kotlin 2.0.0/Kotlin Coroutines 1.8.x.
Обновление: я пытался удалить модификатор suspend, но все равно столкнулся с ошибкой.
Я попробовал удалить suspend на простом примере, получил тот же результат.




Обычно мы используем аннотацию @Configuration как место, где определяются «основные» компоненты.
А затем используйте аннотацию @Component (или @Service, @Repository), чтобы определить «конкретные» компоненты, которые используют «основные» компоненты.
Вот почему класс MyConfig будет инициализирован раньше MyMbean класса.
Если хочешь, попробуй, сделай это. Предлагаю 2 решения:
Решение 1
Сделайте MyConfig зависимым от myBean и переместите @ConditionalOnExpression при создании метода компонента:
@Configuration
@ConditionalOnBean(name = "myBean")
public class MyConfig {
@Bean
@ConditionalOnExpression("@myBean.isEnabled('test')")
public String simpleBean() {
return "simpleBean";
}
}
Примечание: используйте @, чтобы получить ссылки на компоненты.
Решение 2
Вам необходимо настроить собственное условие и создать компонент вручную:
@Configuration
@Conditional(MyBeanCondition.class)
public class MyConfig {}
public class MyBeanCondition implements ConfigurationCondition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
MyMbean mybean = context.getBeanFactory().createBean(MyMbean.class);
return mybean.isEnabled("test");
}
@Override
public ConfigurationPhase getConfigurationPhase() {
return ConfigurationPhase.REGISTER_BEAN;
}
}
Для выполнения функции приостановки необходимо находиться в контексте сопрограммы и, как правило, иметь ее поддержку. Я сомневаюсь, что Spring делает это для
@ConditionalOnExpression. Если это что-то простое, например чтение из файла и т. д., я предлагаю создать еще одну функцию, которая обертывает первую вrunBlocking. Это проще всего сделать и не должно вызвать проблем.