Spring 应用上下文获取 Bean 的常用姿势实例总结

所属分类: 软件编程 / java 阅读数: 44
收藏 0 赞 0 分享

本文实例讲述了Spring 应用上下文获取 Bean 的常用姿势。分享给大家供大家参考,具体如下:

1. 前言

通常,在Spring应用程序中,当我们使用 @Bean@Service@Controller@Configuration 或者其它特定的注解将 Bean 注入 Spring IoC 。然后我们可以使用 Spring 框架提供的 @Autowired 或者 JSR250JSR330 规范注解来使用由 Spring IoC 管理的 Bean

2. 从应用程序上下文中获取 Bean

今天我们将来学习如何从 ApplicationContext 中获取 Bean 。因为有些情况下我们不得不从应用程序上下文中来获取 Bean

2.1 获取所有的 Bean

ApplicationContext 提供了获取所有已经成功注入 Spring IoC 容器的 Bean 名称的方法 getBeanDefinitionNames() 。然后我们可以借助于其 getBean(String name) 方法使用 Bean 名称获取特定的 Bean。 我们使用之前文章中介绍的 CommandLineRunner 接口来打印一下结果。

 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.CommandLineRunner;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.context.ApplicationContext;
 
 import java.util.stream.Stream;
 
 /**
 * @author Felordcn
 */
 @SpringBootApplication
 public class WarSpringBootApplication implements CommandLineRunner {
   @Autowired
   private ApplicationContext applicationContext;
 
   public static void main(String[] args) {
     SpringApplication.run(WarSpringBootApplication.class, args);
 
 
   }
 
   @Override
   public void run(String... args) throws Exception {
     String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
 
     Stream.of(beanDefinitionNames).forEach(beanName->{
       System.out.println("beanName : " + beanName);
 
       Object bean = applicationContext.getBean(beanName);
 
       System.out.println("Spring bean : " + bean);
     });
 
   }
 }

运行应用会输出:

2019-11-05 22:15:54.392 INFO 6356 --- [      main] cn.felord.war.WarSpringBootApplication  : Started WarSpringBootApplication in 4.663 seconds (JVM running for 7.58)
 beanName : org.springframework.context.annotation.internalConfigurationAnnotationProcessor
 Spring bean : org.springframework.context.annotation.ConfigurationClassPostProcessor@6c44052e
 beanName : org.springframework.context.annotation.internalAutowiredAnnotationProcessor
 Spring bean : org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor@5c371e13
 beanName : org.springframework.context.annotation.internalCommonAnnotationProcessor
 Spring bean : org.springframework.context.annotation.CommonAnnotationBeanPostProcessor@530a8454
 beanName : org.springframework.context.event.internalEventListenerProcessor
 Spring bean : org.springframework.context.event.EventListenerMethodProcessor@1e34c607
 beanName : org.springframework.context.event.internalEventListenerFactory
 Spring bean : org.springframework.context.event.DefaultEventListenerFactory@5215cd9a
 beanName : fooController
 Spring bean : cn.felord.war.controller.FooController@31198ceb
 beanName : IServiceImpl
 Spring bean : cn.felord.war.controller.IServiceImpl@51671b08
 <more...>

2.2 通过名称获取特定的 Bean

从上面打印的信息我们也能看出来一些端倪。

  • 有的 beanName 是类全限定名。
  • @Component@Repository@Service@Controller等注解创建 Bean 时,如果不指定bean名称,名称的默认规则是类名的首字母小写,如 cn.felord.war.controller.FooControllerfooController。如果类名前两个或以上个字母都是大写,那么名称与类名一样,如 cn.felord.war.controller.IServiceImplIServiceImpl
  • @Bean 标识的 Bean 默认 为方法名称。
  • 配置类相关注解 @Configuration 一般使用类全限定名。

但是请注意:如果你在声明 Bean 的时候指定了名称就只是你指定的名称 。如果我们熟悉这些规则,使用上面提到的getBean(String name) 方法不失为一种好办法。

2.3 通过类型来获取 Bean

如果我们不清楚我们想要的特定类型 Bean 的名称,我们可以根据类型来获取 BeanApplicationContext 提供了可以加载特定类型的 Bean 的所有 Bean 的方法getBeansOfType()。它将返回 Map <String,Object> 其中键是 Bean 名称,而值是 Bean 的实际对象。

我们修改 2.1 章节 例子中的 run 方法:

   @Override
   public void run(String... args) throws Exception {
     Map<String, FooController> beansOfType = applicationContext.getBeansOfType(FooController.class);
 
 
     beansOfType.forEach((beanName,bean)->{
       System.out.println("beanName : " + beanName);
       System.out.println("bean : " + bean);
     });
   }

再次运行,控制台打印出:

beanName : fooController
 bean : cn.felord.war.controller.FooController@545f80bf

2.4 获取特定 Bean 声明注解标记的 Bean

ApplicationContextgetBeansWithAnnotation() 方法可以让我们获取 @Service@Controller或任何其它可以用来创建 Bean 的注解创建的 Bean

   @Override
   public void run(String... args) throws Exception {
     Map<String, Object> beansWithAnnotation = applicationContext.getBeansWithAnnotation(Controller.class);
 
     beansWithAnnotation.forEach((beanName,bean)->{
       System.out.println("beanName : " + beanName);
       System.out.println("bean : " + bean);
     });
   }

打印出:

beanName : fooController
 bean : cn.felord.war.controller.FooController@18ca3c62
 beanName : basicErrorController
 bean : org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController@2c0f7678

3. 总结

在本文中,我们学习如何从 Spring 应用上下文中获取所有 Bean 的列表。有时我们需要检查我们期望的 Bean 是否在 Spring 上下文中加载,或者我们需要检查 Spring IoC 声明的特定的 Bean 。当然你可以开启Spring Boot Actuatorbeans 端点来获取所有的 Bean 信息。

更多关于java相关内容感兴趣的读者可查看本站专题:《Spring框架入门与进阶教程》、《Java数据结构与算法教程》、《Java操作DOM节点技巧总结》、《Java文件与目录操作技巧汇总》和《Java缓存操作技巧汇总

希望本文所述对大家java程序设计有所帮助。

更多精彩内容其他人还在看

利用MultipartFile实现文件上传功能

这篇文章主要为大家详细介绍了利用MultipartFile实现文件上传功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

Java编程实现NBA赛事接口调用实例代码

这篇文章主要介绍了Java编程实现NBA赛事接口调用实例代码,具有一定参考价值,需要的朋友可以了解下。
收藏 0 赞 0 分享

Java编程之双重循环打印图形

这篇文章主要介绍了Java编程之双重循环打印图形,属于Java编程基础练习部分,具有一定参考价值,需要的朋友可以了解下。
收藏 0 赞 0 分享

java基础学习JVM中GC的算法

这篇文章主要介绍了java基础学习JVM中GC的算法,通过图文加深对GC算法思路的理解。
收藏 0 赞 0 分享

Java编程Post数据请求和接收代码详解

这篇文章主要介绍了Java编程Post数据请求和接收代码详解,涉及enctype的三种编码,post与get等相关内容,具有一定参考价值,需要的朋友可以了解下。
收藏 0 赞 0 分享

Retrofit+Rxjava实现文件上传和下载功能

这篇文章主要介绍了Retrofit+Rxjava实现文件上传和下载功能,文中提到了单文件上传和多文件上传及相关参数的请求,需要的朋友参考下吧
收藏 0 赞 0 分享

Retrofit+Rxjava下载文件进度的实现

这篇文章主要介绍了Retrofit+Rxjava下载文件进度的实现,非常不错,具有参考借鉴价值,需要的朋友可以参考下
收藏 0 赞 0 分享

java检查服务器的连通两种方法代码分享

这篇文章主要介绍了java检查服务器的连通两种方法代码分享,涉及ping的介绍以及检查服务器连通的两种方法代码示例,具有一定参考价值,需要的朋友可以了解下。
收藏 0 赞 0 分享

Java/Android 获取网络重定向文件的真实URL的示例代码

本篇文章主要介绍了Java/Android 获取网络重定向文件的真实URL的示例代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

java并发编程之同步器代码示例

这篇文章主要介绍了java并发编程之同步器代码示例,分享了相关代码,具有一定参考价值,需要的朋友可以了解下。
收藏 0 赞 0 分享
查看更多