1. 程式人生 > 程式設計 >Spring 應用上下文獲取 Bean 的常用姿勢例項總結

Spring 應用上下文獲取 Bean 的常用姿勢例項總結

本文例項講述了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 Actuator 的 beans 端點來獲取所有的 Bean 資訊。

更多關於java相關內容感興趣的讀者可檢視本站專題:《Spring框架入門與進階教程》、《Java資料結構與演算法教程》、《Java操作DOM節點技巧總結》、《Java檔案與目錄操作技巧彙總》和《Java快取操作技巧彙總》

希望本文所述對大家java程式設計有所幫助。