'資深程序員總結:徹底理解Spring容器和應用上下文'

程序員 XML Java 軟件 Tomcat 蘋果公司 IT技術分享 2019-08-28
"

有了Spring之後,通過依賴注入的方式,我們的業務代碼不用自己管理關聯對象的生命週期。業務代碼只需要按照業務本身的流程,走啊走啊,走到哪裡,需要另外的對象來協助了,就給Spring說,我想要個對象——於是Spring就很貼心的給你個對象。

"

有了Spring之後,通過依賴注入的方式,我們的業務代碼不用自己管理關聯對象的生命週期。業務代碼只需要按照業務本身的流程,走啊走啊,走到哪裡,需要另外的對象來協助了,就給Spring說,我想要個對象——於是Spring就很貼心的給你個對象。

資深程序員總結:徹底理解Spring容器和應用上下文

聽起來似乎很簡單,使用起來也不難,但是如果僅僅是這樣的拿來主義,倒也灑脫,不用費什麼腦子。。。可是,你就真的不關心,Spring是從哪裡把對象給你的嗎?

如果你想要了解Spring深一些,而不僅僅是拿來用用,那麼你就應該好好思考一下上訴問題,不然,這篇博文你還看個剷剷啊。。。

"

有了Spring之後,通過依賴注入的方式,我們的業務代碼不用自己管理關聯對象的生命週期。業務代碼只需要按照業務本身的流程,走啊走啊,走到哪裡,需要另外的對象來協助了,就給Spring說,我想要個對象——於是Spring就很貼心的給你個對象。

資深程序員總結:徹底理解Spring容器和應用上下文

聽起來似乎很簡單,使用起來也不難,但是如果僅僅是這樣的拿來主義,倒也灑脫,不用費什麼腦子。。。可是,你就真的不關心,Spring是從哪裡把對象給你的嗎?

如果你想要了解Spring深一些,而不僅僅是拿來用用,那麼你就應該好好思考一下上訴問題,不然,這篇博文你還看個剷剷啊。。。

資深程序員總結:徹底理解Spring容器和應用上下文

你可以這樣去思考:Spring既然要負責應用程序中那麼多對象的創建管理,就像蘋果要生產那麼多的手機(對象)一樣,肯定有一個專門搞對象的地方。蘋果生產手機的地方叫工廠,比如富士康,但放在軟件開發中,對於Spring搞對象的地方我們就不叫工廠了,而叫做容器。

是的,容器的概念在java中你最熟悉的莫過於Tomcat了,它正是一個運行Servlet的web容器,而Spring要想實現依賴注入功能,就離不開對象生產的容器——如果沒有容器負責對象的創建管理,你的程序代碼只是喊要對象了,Spring也無處給你啊。實際上,容器是Spring框架實現功能的核心,容器不只是幫我們創建了對象那麼簡單,它負責了對象整個的生命週期的管理——創建、裝配、銷燬。

關於Spring的這個容器你最常聽聞的一個術語就是IOC容器。所謂IOC,是一種叫控制反轉的編程思想,網上有很通俗易懂的總結,我就不胡亂闡述了。總之一句話,我的應用程序裡不用再過問對象的創建和管理對象之間的依賴關係了,都讓IOC容器給代勞吧,也就是說,我把對象創建、管理的控制權都交給Spring容器,這是一種控制權的反轉,所以Spring容器才能稱為IOC容器。不過這裡要釐清一點:並不是說只有Spring的容器才叫IOC容器,基於IOC容器的框架還有很多,並不是Spring特有的。

好了,終於把Spring的容器概念闡述的差不多了,但有什麼卵用呢?光有容器你其實什麼都幹不了!你以為容器那麼科幻,跟叮噹貓面前的百寶袋一樣,你想要啥它就給你啥?實際上,容器裡面什麼都沒有,決定容器裡面放什麼對象的是我們自己,決定對象之間的依賴關係的,也是我們自己,容器只是給我們提供一個管理對象的空間而已。那麼,我們怎麼向容器中放入我們需要容器代為管理的對象呢?這就涉及到Spring的應用上下文了。

"

有了Spring之後,通過依賴注入的方式,我們的業務代碼不用自己管理關聯對象的生命週期。業務代碼只需要按照業務本身的流程,走啊走啊,走到哪裡,需要另外的對象來協助了,就給Spring說,我想要個對象——於是Spring就很貼心的給你個對象。

資深程序員總結:徹底理解Spring容器和應用上下文

聽起來似乎很簡單,使用起來也不難,但是如果僅僅是這樣的拿來主義,倒也灑脫,不用費什麼腦子。。。可是,你就真的不關心,Spring是從哪裡把對象給你的嗎?

如果你想要了解Spring深一些,而不僅僅是拿來用用,那麼你就應該好好思考一下上訴問題,不然,這篇博文你還看個剷剷啊。。。

資深程序員總結:徹底理解Spring容器和應用上下文

你可以這樣去思考:Spring既然要負責應用程序中那麼多對象的創建管理,就像蘋果要生產那麼多的手機(對象)一樣,肯定有一個專門搞對象的地方。蘋果生產手機的地方叫工廠,比如富士康,但放在軟件開發中,對於Spring搞對象的地方我們就不叫工廠了,而叫做容器。

是的,容器的概念在java中你最熟悉的莫過於Tomcat了,它正是一個運行Servlet的web容器,而Spring要想實現依賴注入功能,就離不開對象生產的容器——如果沒有容器負責對象的創建管理,你的程序代碼只是喊要對象了,Spring也無處給你啊。實際上,容器是Spring框架實現功能的核心,容器不只是幫我們創建了對象那麼簡單,它負責了對象整個的生命週期的管理——創建、裝配、銷燬。

關於Spring的這個容器你最常聽聞的一個術語就是IOC容器。所謂IOC,是一種叫控制反轉的編程思想,網上有很通俗易懂的總結,我就不胡亂闡述了。總之一句話,我的應用程序裡不用再過問對象的創建和管理對象之間的依賴關係了,都讓IOC容器給代勞吧,也就是說,我把對象創建、管理的控制權都交給Spring容器,這是一種控制權的反轉,所以Spring容器才能稱為IOC容器。不過這裡要釐清一點:並不是說只有Spring的容器才叫IOC容器,基於IOC容器的框架還有很多,並不是Spring特有的。

好了,終於把Spring的容器概念闡述的差不多了,但有什麼卵用呢?光有容器你其實什麼都幹不了!你以為容器那麼科幻,跟叮噹貓面前的百寶袋一樣,你想要啥它就給你啥?實際上,容器裡面什麼都沒有,決定容器裡面放什麼對象的是我們自己,決定對象之間的依賴關係的,也是我們自己,容器只是給我們提供一個管理對象的空間而已。那麼,我們怎麼向容器中放入我們需要容器代為管理的對象呢?這就涉及到Spring的應用上下文了。

資深程序員總結:徹底理解Spring容器和應用上下文

什麼是應用上下文呢,你可以簡單的理解成就是將你需要Spring幫你管理的對象放入容器的那麼一種。。一種。。額。。一種容器對象——是的,應用上下文即是Spring容器的一種抽象化表述;而我們常見的ApplicationContext本質上說就是一個維護Bean定義以及對象之間協作關係的高級接口。額,聽起來是不是很抽象拗口?那你再讀一遍呢。。。

這裡,我們必須明確,Spring的核心是容器,而容器並不唯一,框架本身就提供了很多個容器的實現,大概分為兩種類型:一種是不常用的BeanFactory,這是最簡單的容器,只能提供基本的DI功能;還有一種就是繼承了BeanFactory後派生而來的應用上下文,其抽象接口也就是我們上面提到的的ApplicationContext,它能提供更多企業級的服務,例如解析配置文本信息等等,這也是應用上下文實例對象最常見的應用場景。

有了上下文對象,我們就能向容器註冊需要Spring管理的對象了。對於上下文抽象接口,Spring也為我們提供了多種類型的容器實現,供我們在不同的應用場景選擇:

  • ① AnnotationConfigApplicationContext:從一個或多個基於java的配置類中加載上下文定義,適用於java註解的方式;
  • ② ClassPathXmlApplicationContext:從類路徑下的一個或多個xml配置文件中加載上下文定義,適用於xml配置的方式;
  • ③ FileSystemXmlApplicationContext:從文件系統下的一個或多個xml配置文件中加載上下文定義,也就是說系統盤符中加載xml配置文件;
  • ④ AnnotationConfigWebApplicationContext:專門為web應用準備的,適用於註解方式;
  • ⑤ XmlWebApplicationContext:從web應用下的一個或多個xml配置文件加載上下文定義,適用於xml配置方式。

有了以上理解,問題就很好辦了。你只要將你需要IOC容器替你管理的對象基於xml也罷,java註解也好,總之你要將需要管理的對象(Spring中我們都稱之問bean)、bean之間的協作關係配置好,然後利用應用上下文對象加載進我們的Spring容器,容器就能為你的程序提供你想要的對象管理服務了。下面,還是貼一下簡單的應用上下文的應用實例:

我們先採用xml配置的方式配置bean和建立bean之間的協作關係:

<?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/beans
http://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>

然後通過應用上下文將配置加載到IOC容器,讓Spring替我們管理對象,待我們需要使用對象的時候,再從容器中獲取bean就ok了:

public class Test {
public static void main(String[] args) {
//加載項目中的spring配置文件到容器
// ApplicationContext context = new ClassPathXmlApplicationContext("resouces/applicationContext.xml");
//加載系統盤中的配置文件到容器
ApplicationContext context = new FileSystemXmlApplicationContext("E:/Spring/applicationContext.xml");
//從容器中獲取對象實例
Man man = context.getBean(Man.class);
man.driveCar();
}
}

以上測試中,我將配置文件applicationContext.xml分別放在項目中和任意的系統盤符下,我只需要使用相應的上下文對象去加載配置文件,最後的結果是完全一樣的。當然,現在項目中越來越多的使用java註解,所以註解的方式必不可少:

//同xml一樣描述bean以及bean之間的依賴關係
@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);
//從容器中獲取對象實例
Man man = context.getBean(Man.class);
man.driveCar();
}
}

自此,Spring容器和應用上下文就算闡述的差不多了,具體的技能點在今後的博文中會慢慢的給大家奉上。

end:如果你覺得本文對你有幫助的話,記得點贊轉發,你的支持就是我更新動力。

"

相關推薦

推薦中...