SpringBoot获取ApplicationContext,再获取bean的名称

Posted TCSN

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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;

以上是关于SpringBoot获取ApplicationContext,再获取bean的名称的主要内容,如果未能解决你的问题,请参考以下文章

Spring事件发布

Spring事件发布

springboot获取jar包路径

springboot全局异常可以获取方法名吗

[Spring Boot] Singleton and Prototype

springboot多任务并行+线程池处理+等待获取执行结果