Не удалось выполнить оценку Spring EL на основе Kotlin Coroutines

Учитывая интерфейс и класс реализации, подобный этому.

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, но все равно столкнулся с ошибкой.

Для выполнения функции приостановки необходимо находиться в контексте сопрограммы и, как правило, иметь ее поддержку. Я сомневаюсь, что Spring делает это для @ConditionalOnExpression. Если это что-то простое, например чтение из файла и т. д., я предлагаю создать еще одну функцию, которая обертывает первую в runBlocking. Это проще всего сделать и не должно вызвать проблем.

broot 27.06.2024 12:21

Я попробовал удалить suspend на простом примере, получил тот же результат.

Hantsy 27.06.2024 16:07
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Версия Java на основе версии загрузки
Версия Java на основе версии загрузки
Если вы зайдете на официальный сайт Spring Boot , там представлен start.spring.io , который упрощает создание проектов Spring Boot, как показано ниже.
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
0
2
63
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Обычно мы используем аннотацию @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;
    }
}

Другие вопросы по теме