Spring 應(yīng)用上下文獲取 Bean 的常用姿勢(shì)實(shí)例總結(jié)
本文實(shí)例講述了Spring 應(yīng)用上下文獲取 Bean 的常用姿勢(shì)。分享給大家供大家參考,具體如下:
1. 前言
通常,在Spring應(yīng)用程序中,當(dāng)我們使用 @Bean,@Service,@Controller,@Configuration 或者其它特定的注解將 Bean 注入 Spring IoC 。然后我們可以使用 Spring 框架提供的 @Autowired 或者 JSR250、JSR330 規(guī)范注解來(lái)使用由 Spring IoC 管理的 Bean 。
2. 從應(yīng)用程序上下文中獲取 Bean
今天我們將來(lái)學(xué)習(xí)如何從 ApplicationContext 中獲取 Bean 。因?yàn)橛行┣闆r下我們不得不從應(yīng)用程序上下文中來(lái)獲取 Bean 。
2.1 獲取所有的 Bean
ApplicationContext 提供了獲取所有已經(jīng)成功注入 Spring IoC 容器的 Bean 名稱(chēng)的方法 getBeanDefinitionNames() 。然后我們可以借助于其 getBean(String name) 方法使用 Bean 名稱(chēng)獲取特定的 Bean。 我們使用之前文章中介紹的 CommandLineRunner 接口來(lái)打印一下結(jié)果。
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);
});
}
}
運(yùn)行應(yīng)用會(huì)輸出:
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 通過(guò)名稱(chēng)獲取特定的 Bean
從上面打印的信息我們也能看出來(lái)一些端倪。
- 有的
beanName是類(lèi)全限定名。 @Component、@Repository、@Service、@Controller等注解創(chuàng)建 Bean 時(shí),如果不指定bean名稱(chēng),名稱(chēng)的默認(rèn)規(guī)則是類(lèi)名的首字母小寫(xiě),如cn.felord.war.controller.FooController為fooController。如果類(lèi)名前兩個(gè)或以上個(gè)字母都是大寫(xiě),那么名稱(chēng)與類(lèi)名一樣,如cn.felord.war.controller.IServiceImpl為IServiceImpl@Bean標(biāo)識(shí)的 Bean 默認(rèn) 為方法名稱(chēng)。- 配置類(lèi)相關(guān)注解
@Configuration一般使用類(lèi)全限定名。
但是請(qǐng)注意:如果你在聲明 Bean 的時(shí)候指定了名稱(chēng)就只是你指定的名稱(chēng) 。如果我們熟悉這些規(guī)則,使用上面提到的getBean(String name) 方法不失為一種好辦法。
2.3 通過(guò)類(lèi)型來(lái)獲取 Bean
如果我們不清楚我們想要的特定類(lèi)型 Bean 的名稱(chēng),我們可以根據(jù)類(lèi)型來(lái)獲取 Bean 。ApplicationContext 提供了可以加載特定類(lèi)型的 Bean 的所有 Bean 的方法getBeansOfType()。它將返回 Map <String,Object> 其中鍵是 Bean 名稱(chēng),而值是 Bean 的實(shí)際對(duì)象。
我們修改 2.1 章節(jié) 例子中的 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);
});
}
再次運(yùn)行,控制臺(tái)打印出:
beanName : fooController bean : cn.felord.war.controller.FooController@545f80bf
2.4 獲取特定 Bean 聲明注解標(biāo)記的 Bean
ApplicationContext 的 getBeansWithAnnotation() 方法可以讓我們獲取 @Service,@Controller或任何其它可以用來(lái)創(chuàng)建 Bean 的注解創(chuàng)建的 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. 總結(jié)
在本文中,我們學(xué)習(xí)如何從 Spring 應(yīng)用上下文中獲取所有 Bean 的列表。有時(shí)我們需要檢查我們期望的 Bean 是否在 Spring 上下文中加載,或者我們需要檢查 Spring IoC 聲明的特定的 Bean 。當(dāng)然你可以開(kāi)啟Spring Boot Actuator 的 beans 端點(diǎn)來(lái)獲取所有的 Bean 信息。
更多關(guān)于java相關(guān)內(nèi)容感興趣的讀者可查看本站專(zhuān)題:《Spring框架入門(mén)與進(jìn)階教程》、《Java數(shù)據(jù)結(jié)構(gòu)與算法教程》、《Java操作DOM節(jié)點(diǎn)技巧總結(jié)》、《Java文件與目錄操作技巧匯總》和《Java緩存操作技巧匯總》
希望本文所述對(duì)大家java程序設(shè)計(jì)有所幫助。
相關(guān)文章
SpringBoot項(xiàng)目打包三方JAR的示例代碼
本篇文章主要介紹了SpringBoot項(xiàng)目打包三方JAR的示例代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-09-09
解決Spring Boot中Druid連接池“discard long time 
本文主要介紹了解決Spring Boot中Druid連接池“discard long time none received connection“警告,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2025-03-03
java用split分割字符串的一個(gè)有趣現(xiàn)象
最近在項(xiàng)目中使用了java中的split分割字符串,發(fā)現(xiàn)了一個(gè)bug,充分了展示了自己對(duì)java底層的認(rèn)知有很多的不足和欠缺。下面將這次的經(jīng)過(guò)總結(jié)出來(lái)分享給大家,有需要的朋友們可以參考借鑒,下面來(lái)一起看看吧。2016-12-12
Java數(shù)據(jù)類(lèi)型轉(zhuǎn)換的示例詳解
Java程序中要求參與的計(jì)算的數(shù)據(jù),必須要保證數(shù)據(jù)類(lèi)型的一致性,如果數(shù)據(jù)類(lèi)型不一致將發(fā)生類(lèi)型的轉(zhuǎn)換。本文將通過(guò)示例詳細(xì)說(shuō)說(shuō)Java中數(shù)據(jù)類(lèi)型的轉(zhuǎn)換,感興趣的可以了解一下2022-10-10
Java多線程Future松獲取異步任務(wù)結(jié)果輕松實(shí)現(xiàn)
這篇文章主要為大家介紹了Java多線程Future松獲取異步任務(wù)結(jié)果輕松實(shí)現(xiàn)方法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04
使用Java實(shí)現(xiàn)在PDF插入頁(yè)眉頁(yè)腳
在處理PDF文檔時(shí),有時(shí)需要為文檔中的每一頁(yè)添加頁(yè)眉和頁(yè)腳,這篇文章主要為大家詳細(xì)介紹了如何使用Java為PDF文件添加頁(yè)眉、頁(yè)腳,感興趣的可以了解下2024-03-03

