Home > OS >  How to create a conditional bean in Spring
How to create a conditional bean in Spring

Time:08-11

I need to create a Conditional Bean in Spring. The use case is as following:

Class 1

In this class we are trying to create the Bean, which should be created for some clients who have the required permission, and for others it will return empty(). Thus the application should boot-up for all the clients without the BeanCreationException

@org.springframework.context.annotation.Configuration
public class SomeBeanConfiguration {

    @Bean
    public Optional<SomeBean> someBean() {
        // whoAmI() ? returns IAmClient_1 - for whom this bean should be created
        // whoAmI() ? returns IAmClient_2 - for whom this bean should not be created
        
        final String somePermission = whoAmI();
        
        try {
            return Optional.of(SomeBean.builder()
                    .withPermission(new SomeCredentialsProvider(somePermission))
                    .build());
        } catch (Exception ex) {
            LOG.error("SomeBean creation exception : ", ex);
        }
        return Optional.empty();
    }
}

Class 2 Where we are using this Bean in Constructor injection

@Bean
public SomeHelper someHelper(Optional<SomeBean> someBean) {
    return new someHelper(someBean);
}

But the someHelper for client, who have permission are also getting an Optional.empty() in constructor.

What I am doing wrong here? Can anyone please help?

CodePudding user response:

You need to change your method that's creating the bean. It should not be returning a bean of type Optional, it should be returning a bean of type SomeBean. Also, consider rewriting your logic to something more understandable, like dropping the catch block and creating the bean based on the output of whoAmI().

@Bean
public SomeBean someBean() {
    // whoAmI() ? returns IAmClient_1 - for whom this bean should be created
    // whoAmI() ? returns IAmClient_2 - for whom this bean should not be created
    
    String somePermission = whoAmI();
    if (somePermission.equals("IAmClient_1") {
       return SomeBean.builder().withPermission(newSomeCredentialsProvider(somePermission)).build());
    } else {
       return null;
    }
}

Now, when you autowire the Optional, the optional will contain the bean for IAmClient_1, and will be empty for all other cases.

In my opinion, it would be better to always construct SomeBean and just modify its behavior based on the value of the permission you're checking, but that's up to you.

  • Related