1. 程式人生 > 實用技巧 >SpringBoot獲取ApplicationContext,再獲取bean的名稱

SpringBoot獲取ApplicationContext,再獲取bean的名稱

SpringBoot獲取ApplicationContext,再獲取bean的名稱

前言

有一天,我正在學SpringCloud,學到hystrix熔斷器。

案例裡面,教我們配置服務消費端的降級方法,此時我的idea在此處報了一個無關緊要的紅線:

@Autowired
private UserFeignClient userFeignClient;

原因是現在有兩個UserFeignClient的bean(一個是動態代理Feign客戶端、另一個是服務降級類)

於是我就突發奇想,想用@Qualifier註解指定注入的bean,但是我不知道bean的名稱,這怎麼辦呢?

SpringBoot獲取ApplicationContext

在百度後,我個人推薦如下方法:

啟動類的SpringApplication.run方法的返回值是ConfigurableApplicationContext,這是ApplicationContext的一個子介面。

SpringApplication.run(UserConsumerApp.class, args);

因此,我們可以在啟動類中用一個靜態ApplicationContext變數來獲取SpringApplication.run的返回值。例如:

package site.tcsn;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.ConfigurableApplicationContext;


@SpringBootApplication
@EnableFeignClients
public class UserConsumerApp {
    public static ConfigurableApplicationContext applicationContext = null;

    public static void main(String[] args) {
        applicationContext = SpringApplication.run(UserConsumerApp.class, args);
        //等到SpringBoot啟動完成後才能呼叫該變數,否則此時applicationContext為null,被呼叫時會報空指標異常。
        System.out.println("SpringBoot啟動完成,applicationContext:"+applicationContext);
    }
    
}

這樣,我們就能在其他類中呼叫啟動類的applicationContext靜態變數來獲取ApplicationContext了。

  • 要注意的是,用這種方法,必須等到SpringBoot啟動完成後才能呼叫該變數,否則此時applicationContext為null,被呼叫時會報空指標異常。

獲取Bean的名稱

呼叫applicationContext.getBeanNames*方法即可。

public void beanTest(){
    /**
     * 該方法用於檢視型別為UserFeignClient.class的bean的名稱
     *          UserConsumerApp.applicationContext是啟動類中獲取的ConfigurableApplicationContext
     */
    ApplicationContext applicationContext = UserConsumerApp.applicationContext;
    System.out.println(applicationContext);
    String[] beanNamesForType = applicationContext.getBeanNamesForType(UserFeignClient.class);
    System.out.println(Arrays.toString(beanNamesForType));
}

最後

通過如上方式,我終於獲得了bean的名稱,並發現feign動態代理類的Bean名稱是固定的。

可以開開心心的用@Qualifier註解指定注入的bean了!

@Autowired
@Qualifier("site.tcsn.feign.UserFeignClient")
private UserFeignClient userFeignClient;