I am trying to have specific beans enabled based on the "functionality" for the deployment, such as a rest interface, a message consumer, an indexer, an archiver, and an admin portal. In some instances the app should have all, some or one of the "functionalities" like local, dev, and qa should have all of the functionalities, but in staging, and production the functionalities should be segregated so that they can have performance improvements, like memory, threads, etc...
To do this I've setup a custom configuration based on the functionality passed in through the command line. I'm using a ConfigurationProperties to determine whether each of the "funcionalities" should be available. I have a custom configuration:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Configuration
@ConfigurationProperties(prefix = "com.example.config.functionality")
public class FunctionalityConfig {
public static final Logger LOGGER = LoggerFactory.getLogger(FunctionalityConfig.class);
private boolean restInterface;
private boolean messageConsumer;
private boolean adminInterface;
private boolean indexing;
private boolean archive;
public void setRestInterface(final boolean restInterface) {
this.restInterface = restInterface;
}
public boolean isRestInterface() {
return restInterface;
}
public void setMessageConsumer(final boolean messageConsumer) {
this.messageConsumer = messageConsumer;
}
public boolean isMessageConsumer() {
return messageConsumer;
}
...
}
Then I have a custom annotation:
...
/**
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
@Documented
@ConditionalOnExpression("#{ functionalityConfig.isRestInterface }")
public @interface ConditionalOnRestInterface {
}
But when I add it to a bean definition like this:
@Component
@ConditionalOnRestInterface
public class RestInterface implements InitializingBean {
private static final Logger LOGGER = LoggerFactory.getLogger(RestInterface.class);
public void afterPropertiesSet() throws Exception {
LOGGER.info("Rest Interface is available.");
}
}
I get the following error: Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1008E: Property or field 'functionalityConfig' cannot be found on object of type 'org.springframework.beans.factory.config.BeanExpressionContext' - maybe not public?
If I get rid of the @ConditionalOnExpression
annotation, everything works, additionally:
in the Application class I have the following lines:
@Value("#{functionalityConfig.restInterface}")
public boolean restInterface;
And they work perfectly. I'm trying to figure out why the @ConditionalOnExpression
isn't picking it up. I've even added the @EnableConfigurationProperties(FunctionalityConfig.class)
annotation to the application, but no change to the exception.