利用靜態(tài)方法獲取spring的bean實(shí)例
1 場景
spring命名空間中的bean,正常情況下可以使用@Autoware注解加在成員變量上注入,注入成功的前提是注入的對象必須已經(jīng)是spring命名空間中的bean才可以。
當(dāng)前有一種需求:通過工具類的靜態(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 注冊bean
spring配置文件中,加載的xml最前面定義上述bean:
<!-- spring上下文句柄 --> <bean id="springContextHolder" class="com.sa.demo.spring.context.SpringContextHolder"/>
3.3 使用
在java代碼的任何一個地方執(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)行該對象的ApplicationContext。 通常這個調(diào)用將用于初始化對象。 在填充普通bean屬性之后,在init回調(diào)之前調(diào)用
表示實(shí)現(xiàn)此接口的bean,將在填充bean屬性之后,bean的init回調(diào)方法之前,調(diào)用此方法。方法的參數(shù)為spring的命名空間ApplicationContext
bean實(shí)現(xiàn)此接口后,會被調(diào)用相應(yīng)方法,取決于以下源碼:
方法路徑:
org.springframework.context.support.ApplicationContextAwareProcessor#postProcessBeforeInitialization org.springframework.context.support.ApplicationContextAwareProcessor#invokeAwareInterfaces
對應(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中注冊的bean實(shí)現(xiàn)了如下接口:
EnvironmentAware EmbeddedValueResolverAware ResourceLoaderAware ApplicationEventPublisherAware MessageSourceAware ApplicationContextAware
均會執(zhí)行上述代碼中對應(yīng)的實(shí)現(xiàn)方法。
4.2 注意事項(xiàng)
(1)此類bean的定義,需在spring最前面定義。
(2)實(shí)現(xiàn)了接口ApplicationContextAware的bean,只能獲取此bean所定義的spring命名空間。
總結(jié)
以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
struts1之簡單mvc示例_動力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要介紹了struts1之簡單mvc示例的相關(guān)資料,需要的朋友可以參考下2017-09-09
MyEclipse打開文件跳轉(zhuǎn)到notepad打開問題及解決方案
windows系統(tǒng)打開README.md文件,每次都需要右鍵選擇notepad打開,感覺很麻煩,然后就把README.md文件打開方式默認(rèn)選擇了notepad,這樣每次雙擊就能打開,感覺很方便,這篇文章主要介紹了MyEclipse打開文件跳轉(zhuǎn)到notepad打開問題,需要的朋友可以參考下2024-03-03
java?Springboot實(shí)現(xiàn)教務(wù)管理系統(tǒng)
這篇文章主要介紹了java?Springboot實(shí)現(xiàn)教務(wù)管理系統(tǒng)的過程,文章圍繞實(shí)現(xiàn)過程展開全文詳細(xì)內(nèi)容,具有一定的參考價值,需要的朋友可以參考一下,希望對你有所幫助2021-11-11
利用Java實(shí)現(xiàn)簡單的猜數(shù)字小游戲
這篇文章主要為大家詳細(xì)介紹了如何利用java語言實(shí)現(xiàn)猜數(shù)字小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-04-04
實(shí)例講解Java讀取一般文本文件和word文檔的方法
讀取一般文本文件很好辦,調(diào)用Java自帶的io包里的類即可,富文本的doc文件我們可以用Apache的poi項(xiàng)目中的WordExtractor,這里我們一起來以實(shí)例講解Java讀取一般文本文件和word文檔的方法2016-06-06
Hibernate雙向多對多映射關(guān)系配置代碼實(shí)例
這篇文章主要介紹了Hibernate雙向多對多映射關(guān)系配置代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-10-10
Spring 處理 HTTP 請求參數(shù)注解的操作方法
這篇文章主要介紹了Spring 處理 HTTP 請求參數(shù)注解的操作方法,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友參考下吧2024-04-04
Java報(bào)錯:Error:java:?程序包org.springframework.boot不存在解決辦法
建完springboot項(xiàng)目時,點(diǎn)擊啟動,有可能會報(bào)錯,下面這篇文章主要給大家介紹了關(guān)于Java報(bào)錯:Error:java:?程序包org.springframework.boot不存在的解決辦法,需要的朋友可以參考下2024-02-02

