Published on

Using Spring ConditionalOnBean to Conditionally Build a Bean

Authors

In our project we have a web service client module that holds the different web service clients that we use. We have a utility module within this that has a factory responsible for building a web service credentials bean off of a properties bean in the context. This factory helps ensure that our client requests contain non-empty and none-null credentials.

This works really well when the service being integrated with requires credentials but if the service does not, it results in the Spring context not starting up. This is because the factory is expecting there to be a properties bean with the credentials in the context which is not there.

There are a number of ways that this could be resolved like having a default implementation that has empty values for the credential fields. This would then require the factory to check the bean type before continuing - this felt a bit hacky. In the end I saw that Spring boot has a configuration module which provides annotations to assist with Java configuration. One that stood out was the @CondtionalOnBean which according to the documentation: "Conditional that only matches when the specified bean classes and/or names are already contained in the Bean Factory." This is exactly what I needed! To use this I removed the @Compoment annotation from the credentials factory and created a @Configuration bean for this. I then used code similar to the following:

@Configuration
class CredentialsFactoryConfiguration{
      @Bean
@CondtionalOnBean(WebServiceCredentials::class)
fun credentialsFactory(@Autowired credentialProperties : CredentialProperties) : CredentialsFactory {
         return MyCredentialsFactory(credentialProperties)
   }
}