Given an interface and an implementation class like this.
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{
}
}
When applied it on the @ConditonalOnExpression
like this.
@Configuration
@ConditionalOnExpression("#myBean.isEnabled('test')")
class MyConfig{}
For the EL string, I have tried #{myBean.isEnabled('test')}
etc. None worked.
EL1008E: Property or field 'myBean' cannot be found on object of type
'org.springframework.beans.factory.config.BeanExpressionContext'
- maybe not public or not valid?
I was using the latest Spring Boot 3.3.1 and Kotlin 2.0.0/Kotlin Coroutines 1.8.x.
Update: I have tried to remove the suspend
modifier but still encountered failure.
We normally use @Configuration
annotation as place where "core" beans has been defined.
And then use @Component
(or @Service
, @Repository
) annotation to define "specific" beans which use "core" beans.
That why MyConfig
class will be init before MyMbean
class.
If you want to try do that. I suggest 2 solution:
Solution 1
Make MyConfig
depends on myBean
and move @ConditionalOnExpression
on creating bean method:
@Configuration
@ConditionalOnBean(name = "myBean")
public class MyConfig {
@Bean
@ConditionalOnExpression("@myBean.isEnabled('test')")
public String simpleBean() {
return "simpleBean";
}
}
Note: use @
to get bean references
Solution 2
You have to customize own condition and create bean manually:
@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;
}
}