Yves Martin
Yves Martin

Reputation: 10361

How to split Spring Conditional configuration?

My application uses its own Spring configuration Condition to provide beans according to setup, but because of volumes, I expect to split long @Configuration instead of adding @Conditional to tens of beans.

At the moment, my main security configuration looks like

@Configuration @EnableOAuth2Client @EnableWebSecurity
@Import(OptionalAuthenticationConfiguration.class)
public class WebshopSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired(required = false)
    private OptionalAuthenticationConfiguration auth;

And here is conditional configuration

@Configuration
@Conditional(MyCondition.class)
public class OptionalAuthenticationConfiguration {
[...]

Because of @Conditional on optional configuration, @Import annotation fails with

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'webshopSecurityConfig': Injection of autowired dependencies failed; nested exception is 
org.springframework.beans.factory.BeanCreationException: Could not autowire field: private OptionalAuthenticationConfiguration
WebshopSecurityConfig.auth; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException:
No qualifying bean of type [OptionalAuthenticationConfiguration] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency.
Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

Even if bean attribute WebshopSecurityConfig.auth has required = false.

Is there a way to achieve such conditional configuration splitting in Spring?

Upvotes: 0

Views: 674

Answers (2)

Yves Martin
Yves Martin

Reputation: 10361

What I described in this question is expected to work... as far as "MyCondition" properly returns true, and my trouble was there.

Project context was far more complex than shown here: "OptionalAuthenticationConfiguration" is in fact a Spring Security SAML setup which expects many beans from "WebSecurityConfigurerAdapter".

As a result, my code ended with circular "@Import" between these two configurations. I had to move 5 beans from "OptionalAuthenticationConfiguration" to "WebshopSecurityConfig" and make each of them "@Conditional".

Upvotes: 0

finrod
finrod

Reputation: 82

Make OptionalAuthenticationConfiguration an interface with two implementations.

An actual implementation with @Conditional(MyCondition.class) and an empty implementation with @ConditionalOnMissingBean.

This way when MyCondition doesn't allow the configuration to be created, it will get replaced by a placeholder empty implementation.

Upvotes: 2

Related Questions