Java中Spring獲取bean方法小結(jié)
Spring是一個(gè)輕量級(jí)的控制反轉(zhuǎn)(IoC)和面向切面(AOP)的容器框架,如何在程序中獲取Spring配置的bean呢?
Bean工廠(com.springframework.beans.factory.BeanFactory)是Spring框架最核心的接口,它提供了高級(jí)IoC的配置機(jī)制。BeanFactory使管理不同類型的Java對(duì)象成為可能,應(yīng)用上下文(com.springframework.context.ApplicationContext)建立在BeanFactory基礎(chǔ)之上,提供了更多面向應(yīng)用的功能,它提供了國(guó)際化支持和框架事件體系,更易于創(chuàng)建實(shí)際應(yīng)用。我們一般稱BeanFactory為IoC容器,而稱ApplicationContext為應(yīng)用上下文。但有時(shí)為了行文方便,我們也將ApplicationContext稱為Spring容器。
對(duì)于兩者的用途,我們可以進(jìn)行簡(jiǎn)單劃分:BeanFactory是Spring框架的基礎(chǔ)設(shè)施,面向Spring本身;ApplicationContext面向使用Spring框架的開(kāi)發(fā)者,幾乎所有的應(yīng)用場(chǎng)合我們都直接使用ApplicationContext而非底層的BeanFactory。
ApplicationContext的初始化和BeanFactory有一個(gè)重大的區(qū)別:BeanFactory在初始化容器時(shí),并未實(shí)例化Bean,直到第一次訪問(wèn)某個(gè)Bean時(shí)才實(shí)例目標(biāo)Bean;而ApplicationContext則在初始化應(yīng)用上下文時(shí)就實(shí)例化所有單實(shí)例的Bean。因此ApplicationContext的初始化時(shí)間會(huì)比BeanFactory稍長(zhǎng)一些
本文不涉及通過(guò) @Resource 、 @Autowired 自動(dòng)注入,僅僅通過(guò) ApplicationContext 獲取 Sping 配置文件中的 Bean 。
要獲取XML中配置的Bean,最關(guān)鍵的是獲取org.springframework.context.ApplicationContext
第一種獲取 ApplicationContext 的方法:
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
ApplicationContext applicationContext = new FileSystemXmlApplicationContext("applicationContext.xml");
或者
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
private ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
這種方式實(shí)例化applicationContext是非常耗時(shí)的,這種方式適用于采用Spring框架的獨(dú)立應(yīng)用程序,僅僅推薦使用在程序需要通過(guò)配置文件手工初始化Spring的情況。ApplicationContext的主要實(shí)現(xiàn)類是ClassPathXmlApplicationContext和FileSystemXmlApplicationContext,前者默認(rèn)從類路徑加載配置文件,后者默認(rèn)從文件系統(tǒng)中裝載配置文件
例子:
public class BeanManager {
private static ApplicationContext context = new ClassPathXmlApplicationContext("appcontext.xml") ;
public static Object getBean(String beanId) {
return context.getBean(beanId);
}
}
在 web.xml 中寫(xiě)一個(gè) servlet ,自動(dòng)啟動(dòng), init 方法中調(diào)用一下 BeanManager
init() throws ServletException {
BeanManager bm = new BeanManager();//可選的,為的是在 web 應(yīng)用啟動(dòng)的時(shí)候就讓 spring 加載 bean 配置。
// 否則會(huì)在第一次調(diào)用 BeanManager 的時(shí)候加載,影響一次速度。
}
在 java 代碼中使用 BeanManager.getBean(String beanId); 來(lái)獲得 bean 實(shí)例。
第二種獲取 ApplicationContext 的方法: 通過(guò)Spring提供的工具類獲取ApplicationContext對(duì)象,專為web工程定制的方法,推薦Web項(xiàng)目中使用。例如:
ServletContext servletContext = request.getSession().getServletContext();
ApplicationContext ac1 = WebApplicationContextUtils .getRequiredWebApplicationContext(ServletContext sc)
ApplicationContext ac2 = WebApplicationContextUtils .getWebApplicationContext(ServletContext sc)
ac1.getBean("beanId");
ac2.getBean("beanId");
通過(guò)javax.servlet.ServletContext 獲取到ApplicationContext實(shí)例對(duì)象,這意味著,必須使用到request、session等等。
這樣,就不能把ApplicationContext對(duì)象設(shè)置為成員變量。需要在每個(gè)具體的方法中通過(guò)request、session等獲取到ServletContext再獲取ApplicationContext實(shí)例。
因此,此方法僅僅推薦使用在可以獲取到ServletContext對(duì)象的Web項(xiàng)目中,并且不需要將ApplicationContext對(duì)象定義為成員變量的情況下。
注意:當(dāng)使用WebApplicationContextUtils獲取ApplicationContext實(shí)例時(shí),需要在web.xml配置文件中添加org.springframework.web.context.ContextLoaderListener監(jiān)聽(tīng)器,否則獲取不到ApplicationContext對(duì)象,返回Null。
配置文件:web.xml
<!--ContextLoaderListener自動(dòng)注入 applicationContext,通過(guò) WebApplicationContextUtils.getWebApplicationContext(request.getSession().getServletContext())獲取 --> <!--Spring配置文件加載位置 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring/appContext.xml,/WEB-INF/spring/appInterceptor.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>
3. 繼承自抽象類ApplicationObjectSupport
抽象類ApplicationObjectSupport提供getApplicationContext()方法,可以方便的獲取到ApplicationContext。Spring初始化時(shí),會(huì)通過(guò)該抽象類的setApplicationContext(ApplicationContext context)方法將ApplicationContext 對(duì)象注入。
4. 繼承自抽象類WebApplicationObjectSupport
通過(guò)繼承org.springframework.web.context.support.WebApplicationObjectSupport使用getWebApplicationContext() 獲取到org.springframework.web.context.WebApplicationContext由于Web應(yīng)用比一般的應(yīng)用擁有更多的特性,因此WebApplicationContext擴(kuò)展了ApplicationContext。WebApplicationContext定義了一個(gè)常量ROOT_WEB_APPLICATION_ CONTEXT_ATTRIBUTE,在上下文啟動(dòng)時(shí),WebApplicationContext實(shí)例即以此為鍵放置在ServletContext的屬性列表中,因此我們可以直接通過(guò)以下語(yǔ)句從Web容器中獲取WebApplicationContext:
WebApplicationContext wac = (WebApplicationContext)servletContext.getAttribute( WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
5. 實(shí)現(xiàn)接口ApplicationContextAware
實(shí)現(xiàn)該接口的setApplicationContext(ApplicationContext context)方法,并保存ApplicationContext 對(duì)象。Spring初始化時(shí),會(huì)通過(guò)該方法將ApplicationContext 對(duì)象注入。
第三、四、五種方法都需要將類配置在 Spring 配置文件中:
<!--假定ApplicationContextTool為繼承或者實(shí)現(xiàn)了第三、四、五種方法的具體實(shí)現(xiàn)類--> <bean class="com.twovv.utils.ApplicationContextTool"></bean>
否則將獲取不到 ApplicationContext ,返回 Null 。
以上內(nèi)容給大家介紹了Java中Spring獲取bean方法小結(jié),希望大家喜歡。
相關(guān)文章
springboot+vue實(shí)現(xiàn)驗(yàn)證碼功能
這篇文章主要為大家詳細(xì)介紹了springboot+vue實(shí)現(xiàn)驗(yàn)證碼功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-08-08
SpringMVC轉(zhuǎn)發(fā)與重定向參數(shù)傳遞的實(shí)現(xiàn)詳解
這篇文章主要介紹了SpringMVC轉(zhuǎn)發(fā)與重定向參數(shù)傳遞,對(duì)于重定向,可以通過(guò)FlashMap或RedirectAttributes來(lái)在請(qǐng)求間傳遞數(shù)據(jù),因?yàn)橹囟ㄏ蛏婕皟蓚€(gè)獨(dú)立的HTTP請(qǐng)求,而轉(zhuǎn)發(fā)則在同一請(qǐng)求內(nèi)進(jìn)行,數(shù)據(jù)可以直接通過(guò)HttpServletRequest共享,需要的朋友可以參考下2022-07-07
SpringBoot實(shí)現(xiàn)數(shù)據(jù)加密脫敏的示例代碼
這篇文章主要為大家學(xué)習(xí)介紹了SpringBoot如何利用注解+反射+AOP實(shí)現(xiàn)數(shù)據(jù)加密脫敏的功能,文中的示例代碼講解詳細(xì),需要的可以參考一下2023-08-08
Spring AspectJ 實(shí)現(xiàn)AOP的方法你了解嗎
這篇文章主要為大家介紹了Spring AspectJ 實(shí)現(xiàn)AOP的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助2022-01-01
關(guān)于Mybatis的mapper接口函數(shù)重載問(wèn)題
這篇文章主要介紹了關(guān)于Mybatis的mapper接口函數(shù)重載問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-02-02
分享40個(gè)Java多線程問(wèn)題小結(jié)
多個(gè)線程共存于同一JVM進(jìn)程里面,所以共用相同的內(nèi)存空間,較之多進(jìn)程,多線程之間的通信更輕量級(jí),本文給大家分享40個(gè)Java多線程問(wèn)題小結(jié) 的相關(guān)資料,需要的朋友可以參考下2015-12-12
spring?boot?動(dòng)態(tài)生成接口實(shí)現(xiàn)類的場(chǎng)景分析
本文不具體介紹動(dòng)態(tài)代理,主要看一下它在springboot項(xiàng)目中的實(shí)際應(yīng)用,下面我們模仿feign來(lái)實(shí)現(xiàn)一個(gè)調(diào)用三方接口的?httpclient,感謝的朋友跟隨小編一起看看吧2021-11-11
idea?springBoot項(xiàng)目自動(dòng)注入mapper為空?qǐng)?bào)錯(cuò)的解決方法
這篇文章主要介紹了idea?springBoot項(xiàng)目自動(dòng)注入mapper為空?qǐng)?bào)錯(cuò)的解決方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-03-03

