I have this properties class:
import java.util.List;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties("some")
public class SomeProperties {
private List<String> stuff;
public List<String> getStuff() {
return stuff;
}
public void setStuff(List<String> stuff) {
this.stuff = stuff;
}
}
and I enable configuration properties in an @Configuration class like so:
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableConfigurationProperties(SomeProperties.class)
public class SomeAutoConfiguration {
}
In the same class ("SomeAutoConfiguration") I want to create another bean depending if the list attribute in SomeProperties is empty or not. I thought i could use @ConditionalExpression with the following SpEl:
@Bean
@ConditionalOnExpression("!(#someProperties.stuff?.isEmpty()?:true)")
public Object someBean(final SomeProperties someProperties) {
return new Object();
}
The SpEl is correct, but i don't manage to get a hold of the bean containing my properties. Using the above expression i run into
EL1007E:(pos 43): Property or field 'stuff' cannot be found on null
And trying to get the bean through its name like
@Bean
@ConditionalOnExpression("!(@'some.CONFIGURATION_PROPERTIES'.stuff?.isEmpty()?:true)")
public Object someBean(final SomeProperties someProperties) {
return new Object();
}
ends up in
NoSuchBeanDefinitionException: No bean named 'some.CONFIGURATION_PROPERTIES' is defined
Any ideas? I already tried enabling ConfigurationProperties in another class but that didn't work either.
I think the problem that you're facing is that
@Conditions
are evaluated when@Configuration
classes are parsed, so there isn't any guarantee that theSomeProperties
bean has been defined. Even if it were defined, you probably don't want it to be initialized early so I'd recommend a different approach.You could try
@ConditionalOnPropety
, that's the annotation that is used internally by Spring Boot whenever it conditionally wants to enable auto-configuration based on a property. If that's not quite flexible enough you can create your ownCondition
and access theEnvironment
directly to tell if the property value is empty. If you want to support flexible binding you can useRelaxedPropertyResolver
. Here's an example.To complement @PhilWebb answer in regard of Spring Boot 2+,
RelaxedPropertyResolver
has been removed in favor of a more robust alternative namedBinder
. Here's a very simple example :DISCLAIMER: This code is used to phase out some bad practice regarding jackson object mapper, in order to transition some code to the spring boot way to configure an object mapper.