Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to programmatically mark a spring bean as @Primary on startup?

I have multiple DataSources in my application.

The standard org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaConfiguration is annotated with @ConditionalOnSingleCandidate(DataSource.class)

I am attempting to select a @Primary DataSource programmatically.

I have tried a BeanFactoryPostProcessor that naively selects the first DataSource and marks as primary):

    @Bean
    public BeanFactoryPostProcessor beanFactoryPostProcessor() {
        return this::setPrimaryDataSource;
    }

    public void setPrimaryDataSource(ConfigurableListableBeanFactory beanFactory) {

        // Get all DataSource bean names
        String[] dataSourceBeanNames = beanFactory.getBeanNamesForType(DataSource.class);

        // Find primaryBeanName
        String primaryBeanName = dataSourceBeanNames.length > 0 ? dataSourceBeanNames[0] : null;

        // Return appropriate bean
        assert primaryBeanName != null;
        BeanDefinition beanDefinition = beanFactory.getBeanDefinition(primaryBeanName);
        beanDefinition.setPrimary(true);
        LOGGER.info("Primary DataSource: {}", primaryBeanName);

    }

However, this does not appear to work - the @ConditionalOnSingleCandidate(DataSource.class) check on HibernateJpaConfiguration still fails.

Is there anywhere else I can put this code such that it will be executed before the check for @ConditionalOnSingleCandidate?

like image 742
P Liu Avatar asked Dec 18 '25 10:12

P Liu


1 Answers

BeanFactoryPostProcessor worked for me:

@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {

        // logic to retrieve your bean name
        String beanName = beanFactory.getBeanNamesForType(MyService.class)[0];
        
        BeanDefinition bd = beanFactory.getBeanDefinition(beanName);
        bd.setPrimary(true);
    }

}
like image 91
stoldo Avatar answered Dec 21 '25 00:12

stoldo