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;