利用靜態(tài)方法獲取spring的bean實(shí)例
1 場(chǎng)景
spring命名空間中的bean,正常情況下可以使用@Autoware注解加在成員變量上注入,注入成功的前提是注入的對(duì)象必須已經(jīng)是spring命名空間中的bean才可以。
當(dāng)前有一種需求:通過(guò)工具類(lèi)的靜態(tài)方法,獲取spring中的bean
2 思路
(1)定義bean
(2)bean實(shí)現(xiàn)ApplicationContextAware接口
3 代碼
3.1 定義bean
/**
* spring上下文句柄
*/
public class SpringContextHolder implements ApplicationContextAware {
/**
* spring上下文
*/
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringContextHolder.applicationContext=applicationContext;
}
/**
* 獲取spring上下文
* @return
*/
public static ApplicationContext getApplicationContext(){
return applicationContext;
}
/**
* 獲取bean
* @param name bean名稱(chēng)
* @param <T>
* @return
*/
public static <T> T getBean(String name){
if(applicationContext==null){
return null;
}
return (T) applicationContext.getBean(name);
}
/**
* 獲取bean
* @param requiredType bean類(lèi)型
* @param <T>
* @return
*/
public static <T> T getBean(Class<T> requiredType){
if(applicationContext==null){
return null;
}
return applicationContext.getBean(requiredType);
}
/**
* 獲取bean
* @param name bean名稱(chēng)
* @param requiredType bean類(lèi)型
* @param <T>
* @return
*/
public static <T> T getBean(String name, Class<T> requiredType){
if(applicationContext==null){
return null;
}
return applicationContext.getBean(name,requiredType);
}
}
3.2 注冊(cè)bean
spring配置文件中,加載的xml最前面定義上述bean:
<!-- spring上下文句柄 --> <bean id="springContextHolder" class="com.sa.demo.spring.context.SpringContextHolder"/>
3.3 使用
在java代碼的任何一個(gè)地方執(zhí)行下面代碼,可以獲取spring中的bean:
SpringContextHolder.getBean("xxxxxx");
SpringContextHolder.getBean("XXX.class")
SpringContextHolder.getBean("xxxxxx","XXX.class")
獲取spring中的命名空間:
ApplicationContext applicationContext=SpringContextHolder.getApplicationContext();
4 擴(kuò)展
4.1 源碼講解
加載原理:
實(shí)現(xiàn)的接口ApplicationContextAware中的方法定義如下:
/**
* Set the ApplicationContext that this object runs in.
* Normally this call will be used to initialize the object.
* <p>Invoked after population of normal bean properties but before an init callback such
* as {@link org.springframework.beans.factory.InitializingBean#afterPropertiesSet()}
* or a custom init-method. Invoked after {@link ResourceLoaderAware#setResourceLoader},
* {@link ApplicationEventPublisherAware#setApplicationEventPublisher} and
* {@link MessageSourceAware}, if applicable.
* @param applicationContext the ApplicationContext object to be used by this object
* @throws ApplicationContextException in case of context initialization errors
* @throws BeansException if thrown by application context methods
* @see org.springframework.beans.factory.BeanInitializationException
*/
void setApplicationContext(ApplicationContext applicationContext) throws BeansException;
翻譯如下:
設(shè)置運(yùn)行該對(duì)象的ApplicationContext。 通常這個(gè)調(diào)用將用于初始化對(duì)象。 在填充普通bean屬性之后,在init回調(diào)之前調(diào)用
表示實(shí)現(xiàn)此接口的bean,將在填充bean屬性之后,bean的init回調(diào)方法之前,調(diào)用此方法。方法的參數(shù)為spring的命名空間ApplicationContext
bean實(shí)現(xiàn)此接口后,會(huì)被調(diào)用相應(yīng)方法,取決于以下源碼:
方法路徑:
org.springframework.context.support.ApplicationContextAwareProcessor#postProcessBeforeInitialization org.springframework.context.support.ApplicationContextAwareProcessor#invokeAwareInterfaces
對(duì)應(yīng)方法如下:
private void invokeAwareInterfaces(Object bean) {
if (bean instanceof EnvironmentAware) {
((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
}
if (bean instanceof EmbeddedValueResolverAware) {
((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
}
if (bean instanceof ResourceLoaderAware) {
((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
}
if (bean instanceof ApplicationEventPublisherAware) {
((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
}
if (bean instanceof MessageSourceAware) {
((MessageSourceAware) bean).setMessageSource(this.applicationContext);
}
if (bean instanceof ApplicationContextAware) {
((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
}
}
相應(yīng)擴(kuò)展部分:
當(dāng)spring中注冊(cè)的bean實(shí)現(xiàn)了如下接口:
EnvironmentAware EmbeddedValueResolverAware ResourceLoaderAware ApplicationEventPublisherAware MessageSourceAware ApplicationContextAware
均會(huì)執(zhí)行上述代碼中對(duì)應(yīng)的實(shí)現(xiàn)方法。
4.2 注意事項(xiàng)
(1)此類(lèi)bean的定義,需在spring最前面定義。
(2)實(shí)現(xiàn)了接口ApplicationContextAware的bean,只能獲取此bean所定義的spring命名空間。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
SpringBoot3匹配Mybatis3的錯(cuò)誤與解決方案
文章指出SpringBoot3與MyBatis3兼容性問(wèn)題,因未更新MyBatis-Plus依賴(lài)至SpringBoot3專(zhuān)用坐標(biāo),導(dǎo)致類(lèi)沖突,解決方案是替換pom中的依賴(lài)為`mybatis-plus-spring-boot3-starter:3.5.12`,并排除舊版本核心庫(kù),確保版本一致性2025-08-08
Java實(shí)現(xiàn)二進(jìn)制與十進(jìn)制之間互相轉(zhuǎn)換的完整代碼
在編程中,數(shù)制轉(zhuǎn)換是一個(gè)非常常見(jiàn)的需求,Java 作為一種高級(jí)語(yǔ)言,提供了便捷的方法來(lái)實(shí)現(xiàn) 二進(jìn)制和 十進(jìn)制之間的轉(zhuǎn)換,本文將介紹 Java 中二進(jìn)制與十進(jìn)制互轉(zhuǎn)的原理與實(shí)現(xiàn)方式,并附上完整代碼示例,2025-08-08
,需要的朋友可以參考下
SpringBoot Mybatis動(dòng)態(tài)數(shù)據(jù)源切換方案實(shí)現(xiàn)過(guò)程
這篇文章主要介紹了SpringBoot+Mybatis實(shí)現(xiàn)動(dòng)態(tài)數(shù)據(jù)源切換方案過(guò)程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04
Spring內(nèi)部bean和級(jí)聯(lián)屬性用法詳解
這篇文章主要介紹了Java內(nèi)部bean和級(jí)聯(lián)屬性用法詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-10-10
Effective Java 在工作中的應(yīng)用總結(jié)
《Effective Java》是一本經(jīng)典的 Java 學(xué)習(xí)寶典,值得每位 Java 開(kāi)發(fā)者閱讀。下面文章即是將書(shū)中和平日工作較密切的知識(shí)點(diǎn)做了部分總結(jié),需要的朋友可以參考下2021-09-09
Java處理時(shí)間格式CST和GMT轉(zhuǎn)換方法示例
這篇文章主要給大家介紹了關(guān)于Java處理時(shí)間格式CST和GMT轉(zhuǎn)換方法的相關(guān)資料,相信很多小伙伴在時(shí)間格式轉(zhuǎn)換的時(shí)候非常頭疼,文中通過(guò)代碼示例介紹的非常詳細(xì),需要的朋友可以參考下2023-09-09

