spring boot中通過註解@Bean聲明的bean的名稱是什麼?

問題

spring boot中我們常常會在configuration類中通過@Bean註解去聲明Bean。
但是很多人不清楚默認情況下,通過@Bean註解聲明的Bean的名稱是什麼?

請問,如下代碼聲明bean的名稱是什麼?

@Configuration
public class LogAutoConfigure {
    @Bean
    public Queue queueTest() {
        return new Queue("log-queue", true);
    }
}

爲什麼我們要關注聲明bean的名稱,這是由於spring容器中的bean默認是單例模式的,如果聲明的bean的名稱一樣,就無法識別出具體調用哪一個。在調用的時候就會出錯。

The bean 'queueTest', defined in class path resource [com/hcf/base/log/config/LogDataSourceConfig.class], could not be registered. A bean with that name has already been defined in class path resource 

試驗

@Configuration
public class LogConfigure {
    @Bean(name="queue-test")
    public Queue queue() {
        return new Queue("log-queue1", true);
    }

    @Bean
    public Queue queueTest() {
        return new Queue("log-queue2", true);
    }
}

使用單元測試去獲取spring容器中的baen

@Component
public class ApplicationContextHelper implements ApplicationContextAware {
    private static ApplicationContext applicationContext;

    public ApplicationContextHelper() {
    }

    /**
     * 實現ApplicationContextAware接口的回調方法,設置上下文環境
     * @param applicationContext
     * @throws BeansException
     */
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        ApplicationContextHelper.applicationContext = applicationContext;
    }

    /**
     * 獲得spring上下文
     * @return
     */
    public  ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    public  Object getBean(String beanName) {
        return applicationContext != null ? applicationContext.getBean(beanName) : null;
    }
}
@SpringBootTest(classes = LogApplication.class)
class LogApplicationTests {
     @Autowired
    ApplicationContextHelper contextHelper;

    @Test
    void testGetBean(){
       Queue queue1 = (Queue) contextHelper.getBean("queue-test");
       System.out.println(queue1);

        Queue queue2 = (Queue) contextHelper.getBean("queueTest");
        System.out.println(queue2);
    }
}

執行單元測試的結果:

Queue [name=log-queue1, durable=true, autoDelete=false, exclusive=false, arguments={}, actualName=log-queue1]
Queue [name=log-queue2, durable=true, autoDelete=false, exclusive=false, arguments={}, actualName=log-queue2]

結論

通過觀察我們不難發現,默認情況下,使用 @Bean聲明一個bean,bean的名稱由方法名決定。此外,可以通過@Bean註解裏面的name屬性主動設置bean的名稱。

注入指定名稱的bean

@Autowired
@Qualifier("queue-test")
private Queue queue;

典型場景

多數據源配置場景:
每個數據源都使用setDataSource()方法配置數據源,所以要使用@Bean(name = “j3sqlDataSource”)中通過name主動說明bean的名字
在這裏插入圖片描述
在這裏插入圖片描述
消息隊列中,多隊列聲明
這裏通過採用不同的方法名,聲明多個隊列和交換器,避免bean的名稱重複
在這裏插入圖片描述
在這裏插入圖片描述

總結

1、spring boot中通過@Bean聲明bean,默認情況下,bean的名稱由方法名決定。另外,可以通過@Bean註解裏面的name屬性主動設置bean的名稱。
2、通過@Autowired和@Qualifier(“queue-test”)結合使用,可以注入指定名稱的bean

更多精彩,關注我吧。
圖注:跟着老萬學java

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章