簡體   English   中英

如何在啟動時以編程方式將 spring bean 標記為 @Primary?

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

我的應用程序中有多個DataSource

標准的org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaConfiguration@ConditionalOnSingleCandidate(DataSource.class)注釋

我正在嘗試以編程方式選擇@Primary DataSource

我嘗試了一個BeanFactoryPostProcessor ,它天真地選擇了第一個 DataSource 並將其標記為主要的):

    @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);

    }

但是,這似乎不起作用 - 對HibernateJpaConfiguration@ConditionalOnSingleCandidate(DataSource.class)檢查仍然失敗。

有沒有其他地方可以放置此代碼,以便在檢查@ConditionalOnSingleCandidate之前執行它?

如果您的代碼在帶有@Configuration 的類中,則該方法需要是靜態的,以便在創建任何 bean 之前更新 bean 定義。

這是 PropertySourcesPlaceholderConfigurer 的示例。

@Configuration
public class AppConfig {

    @Bean
    public static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() {
         return new PropertySourcesPlaceholderConfigurer();
    }

}

文檔中

您可以將@Bean 方法聲明為靜態方法,允許在不將其包含的配置類創建為實例的情況下調用它們。 這在定義后處理器 bean(例如,BeanFactoryPostProcessor 或 BeanPostProcessor 類型)時特別有意義,因為此類 bean 在容器生命周期的早期被初始化,並且應避免在那時觸發配置的其他部分。

BeanFactoryPostProcessor為我工作:

@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);
    }

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM