javascript
彻底理解 Spring 容器和应用上下文
??點(diǎn)擊上方?好好學(xué)java?,選擇?星標(biāo)?公眾號(hào)
重磅資訊、干貨,第一時(shí)間送達(dá) 今日推薦:收藏了!7 個(gè)開(kāi)源的 Spring Boot 前后端分離優(yōu)質(zhì)項(xiàng)目個(gè)人原創(chuàng)+1博客:點(diǎn)擊前往,查看更多 作者:陳本布衣 鏈接:https://www.cnblogs.com/chenbenbuyi/p/8166304.html有了Spring之后,通過(guò)依賴注入的方式,我們的業(yè)務(wù)代碼不用自己管理關(guān)聯(lián)對(duì)象的生命周期。業(yè)務(wù)代碼只需要按照業(yè)務(wù)本身的流程,走啊走啊,走到哪里,需要另外的對(duì)象來(lái)協(xié)助了,就給Spring說(shuō),我想要個(gè)對(duì)象——于是Spring就很貼心的給你個(gè)對(duì)象。聽(tīng)起來(lái)似乎很簡(jiǎn)單,使用起來(lái)也不難,但是如果僅僅是這樣的拿來(lái)主義,倒也灑脫,不用費(fèi)什么腦子。。。可是,你就真的不關(guān)心,Spring是從哪里把對(duì)象給你的嗎?
如果你想要了解Spring深一些,而不僅僅是拿來(lái)用用,那么你就應(yīng)該好好思考一下上訴問(wèn)題,不然,這篇博文你還看個(gè)鏟鏟啊。。。你可以這樣去思考:Spring既然要負(fù)責(zé)應(yīng)用程序中那么多對(duì)象的創(chuàng)建管理,就像蘋(píng)果要生產(chǎn)那么多的手機(jī)(對(duì)象)一樣,肯定有一個(gè)專門搞對(duì)象的地方。蘋(píng)果生產(chǎn)手機(jī)的地方叫工廠,比如富士康,但放在軟件開(kāi)發(fā)中,對(duì)于Spring搞對(duì)象的地方我們就不叫工廠了,而叫做容器。是的,容器的概念在java中你最熟悉的莫過(guò)于Tomcat了,它正是一個(gè)運(yùn)行Servlet的web容器,而Spring要想實(shí)現(xiàn)依賴注入功能,就離不開(kāi)對(duì)象生產(chǎn)的容器——如果沒(méi)有容器負(fù)責(zé)對(duì)象的創(chuàng)建管理,你的程序代碼只是喊要對(duì)象了,Spring也無(wú)處給你啊。實(shí)際上,容器是Spring框架實(shí)現(xiàn)功能的核心,容器不只是幫我們創(chuàng)建了對(duì)象那么簡(jiǎn)單,它負(fù)責(zé)了對(duì)象整個(gè)的生命周期的管理——?jiǎng)?chuàng)建、裝配、銷毀。關(guān)于Spring的這個(gè)容器你最常聽(tīng)聞的一個(gè)術(shù)語(yǔ)就是IOC容器。所謂IOC,是一種叫控制反轉(zhuǎn)的編程思想,網(wǎng)上有很通俗易懂的總結(jié),我就不胡亂闡述了。總之一句話,我的應(yīng)用程序里不用再過(guò)問(wèn)對(duì)象的創(chuàng)建和管理對(duì)象之間的依賴關(guān)系了,都讓IOC容器給代勞吧,也就是說(shuō),我把對(duì)象創(chuàng)建、管理的控制權(quán)都交給Spring容器,這是一種控制權(quán)的反轉(zhuǎn),所以Spring容器才能稱為IOC容器。不過(guò)這里要厘清一點(diǎn):并不是說(shuō)只有Spring的容器才叫IOC容器,基于IOC容器的框架還有很多,并不是Spring特有的。
好了,終于把Spring的容器概念闡述的差不多了,但有什么卵用呢?光有容器你其實(shí)什么都干不了!你以為容器那么科幻,跟叮當(dāng)貓面前的百寶袋一樣,你想要啥它就給你啥?實(shí)際上,容器里面什么都沒(méi)有,決定容器里面放什么對(duì)象的是我們自己,決定對(duì)象之間的依賴關(guān)系的,也是我們自己,容器只是給我們提供一個(gè)管理對(duì)象的空間而已。那么,我們?cè)趺聪蛉萜髦蟹湃胛覀冃枰萜鞔鸀楣芾淼膶?duì)象呢?這就涉及到Spring的應(yīng)用上下文了。什么是應(yīng)用上下文呢,你可以簡(jiǎn)單的理解成就是將你需要Spring幫你管理的對(duì)象放入容器的那么一種。。一種。。額。。一種容器對(duì)象——是的,應(yīng)用上下文即是Spring容器的一種抽象化表述;而我們常見(jiàn)的ApplicationContext本質(zhì)上說(shuō)就是一個(gè)維護(hù)Bean定義以及對(duì)象之間協(xié)作關(guān)系的高級(jí)接口。額,聽(tīng)起來(lái)是不是很抽象拗口?那你再讀一遍呢。。。這里,我們必須明確,Spring的核心是容器,而容器并不唯一,框架本身就提供了很多個(gè)容器的實(shí)現(xiàn),大概分為兩種類型:一種是不常用的BeanFactory,這是最簡(jiǎn)單的容器,只能提供基本的DI功能;還有一種就是繼承了BeanFactory后派生而來(lái)的應(yīng)用上下文,其抽象接口也就是我們上面提到的的ApplicationContext,它能提供更多企業(yè)級(jí)的服務(wù),例如解析配置文本信息等等,這也是應(yīng)用上下文實(shí)例對(duì)象最常見(jiàn)的應(yīng)用場(chǎng)景。有了上下文對(duì)象,我們就能向容器注冊(cè)需要Spring管理的對(duì)象了。對(duì)于上下文抽象接口,Spring也為我們提供了多種類型的容器實(shí)現(xiàn),供我們?cè)诓煌膽?yīng)用場(chǎng)景選擇——
① AnnotationConfigApplicationContext:從一個(gè)或多個(gè)基于java的配置類中加載上下文定義,適用于java注解的方式;
② ClassPathXmlApplicationContext:從類路徑下的一個(gè)或多個(gè)xml配置文件中加載上下文定義,適用于xml配置的方式;
③ FileSystemXmlApplicationContext:從文件系統(tǒng)下的一個(gè)或多個(gè)xml配置文件中加載上下文定義,也就是說(shuō)系統(tǒng)盤(pán)符中加載xml配置文件;
④ AnnotationConfigWebApplicationContext:專門為web應(yīng)用準(zhǔn)備的,適用于注解方式;
⑤ XmlWebApplicationContext:從web應(yīng)用下的一個(gè)或多個(gè)xml配置文件加載上下文定義,適用于xml配置方式。
有了以上理解,問(wèn)題就很好辦了。你只要將你需要IOC容器替你管理的對(duì)象基于xml也罷,java注解也好,總之你要將需要管理的對(duì)象(Spring中我們都稱之問(wèn)bean)、bean之間的協(xié)作關(guān)系配置好,然后利用應(yīng)用上下文對(duì)象加載進(jìn)我們的Spring容器,容器就能為你的程序提供你想要的對(duì)象管理服務(wù)了。下面,還是貼一下簡(jiǎn)單的應(yīng)用上下文的應(yīng)用實(shí)例:
我們先采用xml配置的方式配置bean和建立bean之間的協(xié)作關(guān)系:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.2.xsd"><bean id="man" class="spring.chapter1.domain.Man"><constructor-arg ref="qqCar" /></bean><bean id="qqCar" class="spring.chapter1.domain.QQCar"/> </beans>然后通過(guò)應(yīng)用上下文將配置加載到IOC容器,讓Spring替我們管理對(duì)象,待我們需要使用對(duì)象的時(shí)候,再?gòu)娜萜髦蝎@取bean就ok了:
public class Test { public static void main(String[] args) { //加載項(xiàng)目中的spring配置文件到容器 // ApplicationContext context = new ClassPathXmlApplicationContext("resouces/applicationContext.xml"); //加載系統(tǒng)盤(pán)中的配置文件到容器ApplicationContext context = new FileSystemXmlApplicationContext("E:/Spring/applicationContext.xml"); //從容器中獲取對(duì)象實(shí)例Man man = context.getBean(Man.class);man.driveCar();} }以上測(cè)試中,我將配置文件applicationContext.xml分別放在項(xiàng)目中和任意的系統(tǒng)盤(pán)符下,我只需要使用相應(yīng)的上下文對(duì)象去加載配置文件,最后的結(jié)果是完全一樣的。當(dāng)然,現(xiàn)在項(xiàng)目中越來(lái)越多的使用java注解,所以注解的方式必不可少:
//同xml一樣描述bean以及bean之間的依賴關(guān)系 @Configuration public class ManConfig {@Bean public Man man() { return new Man(car());}@Bean public Car car() { return new QQCar();} } public class Test { public static void main(String[] args) { //從java注解的配置中加載配置到容器ApplicationContext context = new AnnotationConfigApplicationContext(ManConfig.class); //從容器中獲取對(duì)象實(shí)例Man man = context.getBean(Man.class);man.driveCar();} }自此,Spring容器和應(yīng)用上下文就算闡述的差不多了,具體的技能點(diǎn)在今后的博文中會(huì)慢慢的給大家奉上。博文有闡述欠妥或者不準(zhǔn)確的地方,歡迎大神大仙大俠們指正,陳某不勝感激。
總結(jié)
以上是生活随笔為你收集整理的彻底理解 Spring 容器和应用上下文的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Sprinig Boot + Redis
- 下一篇: SpringBoot+MyBatis+S