利用靜態(tài)方法獲取spring的bean實(shí)例
1 場(chǎng)景
spring命名空間中的bean,正常情況下可以使用@Autoware注解加在成員變量上注入,注入成功的前提是注入的對(duì)象必須已經(jīng)是spring命名空間中的bean才可以。
當(dāng)前有一種需求:通過(guò)工具類的靜態(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名稱
* @param <T>
* @return
*/
public static <T> T getBean(String name){
if(applicationContext==null){
return null;
}
return (T) applicationContext.getBean(name);
}
/**
* 獲取bean
* @param requiredType bean類型
* @param <T>
* @return
*/
public static <T> T getBean(Class<T> requiredType){
if(applicationContext==null){
return null;
}
return applicationContext.getBean(requiredType);
}
/**
* 獲取bean
* @param name bean名稱
* @param requiredType bean類型
* @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)此類bean的定義,需在spring最前面定義。
(2)實(shí)現(xiàn)了接口ApplicationContextAware的bean,只能獲取此bean所定義的spring命名空間。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
struts1之簡(jiǎn)單mvc示例_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要介紹了struts1之簡(jiǎn)單mvc示例的相關(guān)資料,需要的朋友可以參考下2017-09-09
Java使用lambda表達(dá)式簡(jiǎn)化代碼的示例詳解
這篇文章主要給大家介紹了Java如何使用lambda表達(dá)式簡(jiǎn)化代碼的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-11-11
MyEclipse打開(kāi)文件跳轉(zhuǎn)到notepad打開(kāi)問(wèn)題及解決方案
windows系統(tǒng)打開(kāi)README.md文件,每次都需要右鍵選擇notepad打開(kāi),感覺(jué)很麻煩,然后就把README.md文件打開(kāi)方式默認(rèn)選擇了notepad,這樣每次雙擊就能打開(kāi),感覺(jué)很方便,這篇文章主要介紹了MyEclipse打開(kāi)文件跳轉(zhuǎn)到notepad打開(kāi)問(wèn)題,需要的朋友可以參考下2024-03-03
java?Springboot實(shí)現(xiàn)教務(wù)管理系統(tǒng)
這篇文章主要介紹了java?Springboot實(shí)現(xiàn)教務(wù)管理系統(tǒng)的過(guò)程,文章圍繞實(shí)現(xiàn)過(guò)程展開(kāi)全文詳細(xì)內(nèi)容,具有一定的參考價(jià)值,需要的朋友可以參考一下,希望對(duì)你有所幫助2021-11-11
Java實(shí)現(xiàn)雙向鏈表(兩個(gè)版本)
這篇文章主要介紹了Java實(shí)現(xiàn)雙向鏈表(兩個(gè)版本)的相關(guān)資料,需要的朋友可以參考下2016-02-02
利用Java實(shí)現(xiàn)簡(jiǎn)單的猜數(shù)字小游戲
這篇文章主要為大家詳細(xì)介紹了如何利用java語(yǔ)言實(shí)現(xiàn)猜數(shù)字小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-04-04
實(shí)例講解Java讀取一般文本文件和word文檔的方法
讀取一般文本文件很好辦,調(diào)用Java自帶的io包里的類即可,富文本的doc文件我們可以用Apache的poi項(xiàng)目中的WordExtractor,這里我們一起來(lái)以實(shí)例講解Java讀取一般文本文件和word文檔的方法2016-06-06
Hibernate雙向多對(duì)多映射關(guān)系配置代碼實(shí)例
這篇文章主要介紹了Hibernate雙向多對(duì)多映射關(guān)系配置代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-10-10
Spring 處理 HTTP 請(qǐng)求參數(shù)注解的操作方法
這篇文章主要介紹了Spring 處理 HTTP 請(qǐng)求參數(shù)注解的操作方法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友參考下吧2024-04-04
Java報(bào)錯(cuò):Error:java:?程序包org.springframework.boot不存在解決辦法
建完springboot項(xiàng)目時(shí),點(diǎn)擊啟動(dòng),有可能會(huì)報(bào)錯(cuò),下面這篇文章主要給大家介紹了關(guān)于Java報(bào)錯(cuò):Error:java:?程序包org.springframework.boot不存在的解決辦法,需要的朋友可以參考下2024-02-02

