ZERO
????持續(xù)更新 請(qǐng)關(guān)注:https://zorkelvll.cn/blogs/zorkelvll/articles/2018/11/18/1542542741019
背景
????本文主要是記錄在學(xué)習(xí)Spring IOC容器過(guò)程中的一些知識(shí)點(diǎn)總結(jié)!
關(guān)鍵詞:工廠方法模式、反射機(jī)制
一、Spring
Spring是一個(gè)開(kāi)源的、輕量級(jí)的J2EE開(kāi)發(fā)框架,核心思想是IOC實(shí)現(xiàn)松耦合,利用AOP將應(yīng)用的業(yè)務(wù)邏輯與系統(tǒng)服務(wù)分離。
二、Spring IOC
**實(shí)現(xiàn)原理:工廠模式 \+ 反射機(jī)制**
** 把IOC容器的工作模式看做是工廠模式的升華,可以把IOC容器看作是一個(gè)工廠,這個(gè)工廠里要生產(chǎn)的對(duì)象都在配置文件中給出定義,然后利用編程語(yǔ)言提供的反射機(jī)制,根據(jù)配置文件中給出的類(lèi)名生成相應(yīng)的對(duì)象。從實(shí)現(xiàn)來(lái)看,IOC是把以前在工廠方法里寫(xiě)死的對(duì)象生成代碼,改變?yōu)橛膳渲梦募?lái)定義,也就是把工廠和對(duì)象生成這兩者獨(dú)立分隔開(kāi)來(lái),目的就是提高靈活性和可維護(hù)性。**
IOC控制反轉(zhuǎn):就是應(yīng)用本身不負(fù)責(zé)所依賴(lài)對(duì)象的創(chuàng)建和維護(hù),而是由外部容器對(duì)依賴(lài)對(duì)象進(jìn)行創(chuàng)建和維護(hù),這種對(duì)依賴(lài)對(duì)象的控制權(quán)轉(zhuǎn)移到了外部容器,稱(chēng)之為控制反轉(zhuǎn);**(->也就是說(shuō)一個(gè)對(duì)象依賴(lài)的其他對(duì)象會(huì)通過(guò)被動(dòng)的方式傳遞進(jìn)來(lái),而不是這個(gè)對(duì)象自己創(chuàng)建或查找依賴(lài)對(duì)象;;可以理解IOC與JNII相反,不是對(duì)象從容器中查找依賴(lài),而是容器在對(duì)象初始化時(shí)不等到對(duì)象請(qǐng)求時(shí)就主動(dòng)將依賴(lài)傳遞給它)**
** DI依賴(lài)注入:與IOC相應(yīng)地會(huì)出現(xiàn)一個(gè)依賴(lài)注入的概念,指在應(yīng)用程序運(yùn)行期間,由外部容器動(dòng)態(tài)地將依賴(lài)對(duì)象注入到組件中,一般通過(guò)構(gòu)造函數(shù)或setter傳遞或接口傳遞**
**Spring IOC容器原理:**就是spring在啟動(dòng)時(shí),會(huì)讀取應(yīng)用程序所提供的Bean配置信息,并在Spring容器中對(duì)應(yīng)生成一份Bean配置注冊(cè)表,然后根據(jù)該注冊(cè)表實(shí)例化Bean,和裝配好Bean之間的依賴(lài)關(guān)系;然后將Bean實(shí)例放到Spring容器的Bean緩存池(HashMap實(shí)現(xiàn))中,最終支撐上層應(yīng)用的運(yùn)行!
簡(jiǎn)言之,就是Spring在啟動(dòng)的時(shí)候,通過(guò)一個(gè)配置文件描述Bean和Bean之間的依賴(lài)關(guān)系,并生成相應(yīng)的配置注冊(cè)表,然后利用java語(yǔ)言的反射機(jī)制實(shí)例化Bean及建立Bean之間的依賴(lài)關(guān)系
反射是Java語(yǔ)言的一個(gè)特性,它允許程序**在運(yùn)行時(shí)(注意不是編譯的時(shí)候)來(lái)進(jìn)行自我檢查并且對(duì)內(nèi)部的成員進(jìn)行操作**
IOC容器初始化過(guò)程
** 定位Resource資源**:由ResourceLoader通過(guò)統(tǒng)一的Resource接口完成對(duì)Resource外部資源的定位,也即BeanDefinition的資源定位
**載入BeanDefinition**:由BeanDefinitionReader讀取、解析定位的Resource資源,也即將用戶定義好的Bean表示成IOC容器的內(nèi)部數(shù)據(jù)結(jié)構(gòu)BeanDefinition
注冊(cè):通過(guò)BeanDefinitionRegistry接口,向IOC容器注冊(cè)上一步中載入的BeanDefinition(其實(shí)是一個(gè)HashMap進(jìn)行管理的),IOC容器通過(guò)HashMap數(shù)據(jù)結(jié)構(gòu)對(duì)BeanDefinition進(jìn)行維護(hù)管理
依賴(lài)注入:是發(fā)生在在應(yīng)用第一次調(diào)用getBean(BeanFactory接口的方法)時(shí)向容器獲取Bean時(shí)進(jìn)行依賴(lài)注入的,若某個(gè)Bean設(shè)置lazyinit屬性,則該Bean在容器初始化時(shí)就會(huì)被依賴(lài)注入
Spring容器 - Spring容器分為兩類(lèi)
BeanFactory:**最常用的BeanFactory實(shí)現(xiàn)就是XmlBeanFactory類(lèi),它根據(jù)XML文件中的定義加載beans,該容器從XML文件讀取配置元數(shù)據(jù)并用它去創(chuàng)建一個(gè)完全配置的系統(tǒng)或應(yīng)用,**BeanFactory是Spring框架的基礎(chǔ)設(shè)施面向Spring本身;
ApplicationContext應(yīng)用上下文:基于BeanFactory之上構(gòu)建,并提供面向應(yīng)用(Spring框架的開(kāi)發(fā)者)的服務(wù)
關(guān)系:ApplicationContext由BeanFactory派生,通過(guò)該類(lèi)很多功能可以直接通過(guò)配置方式實(shí)現(xiàn)(而在BeanFactory中則需要以編程方式實(shí)現(xiàn))
SpringIOC容器中重要的實(shí)現(xiàn)類(lèi)
**BeanDefinition:**Spring**配置文件中每一個(gè)節(jié)點(diǎn)元素**均對(duì)應(yīng)容器中國(guó)的一個(gè)BeanDefinition對(duì)象,描述Bean的配置信息;
**BeanDefinitionRegistry:**該接口提供**向容器手動(dòng)注冊(cè)BeanDefinition對(duì)象**的方法;
**ListableBeanFactory:**該接口定義了**訪問(wèn)容器中Bean基本信息**的若干方法,如Bean個(gè)數(shù)、某一類(lèi)型Bean的配置名、是否包含某一Bean等;
**HierarchicalBeanFactory:**該接口提供**子容器可訪問(wèn)父容器中Bean**的功能,也即通過(guò)該接口SpringIOC容器可以建立父子級(jí)聯(lián)的容器體系(如SpringMVC中表現(xiàn)層Bean位于一個(gè)子容器中,業(yè)務(wù)層和持久層位于父容器中,因此表現(xiàn)層Bean可以引用業(yè)務(wù)層和持久層的Bean,而業(yè)務(wù)層和持久層不能使用表現(xiàn)層Bean);
**ConfigurableBeanFactory:**該接口用于**增強(qiáng)Ioc容器的可定制性**,提供設(shè)置類(lèi)裝載器、屬性編輯器、容器初始化后置處理器等方法;
**AutowireCapableBeanFactory:**該接口定義了可將容器中Bean按照某種規(guī)則(如名字匹配、類(lèi)型匹配)進(jìn)行**自動(dòng)裝配**的方法;
**SingletonBeanRegistry:**該接口提供**運(yùn)行期間向容器注冊(cè)單例實(shí)例Bean**的方法;
三、SpringMVC - WebApplicationContext
** WebApplicationContext是專(zhuān)門(mén)為Web應(yīng)用準(zhǔn)備的(必須在擁有web容器的前提下才能完成啟動(dòng)工作),允許從相對(duì)于Web根目錄的路徑中裝載配置文件完成初始化工作。**
啟動(dòng)過(guò)程:
web容器如tomcat -> web.xml(配置自啟動(dòng)的Servlet或定義Web容器監(jiān)聽(tīng)器) -> Servlet如ContextLoaderServlet,也即在tomcat中創(chuàng)建一個(gè)ServletContext實(shí)例(用于啟動(dòng)WebApplicationContext) -> WebApplicationContext中引用ServletContext并將整個(gè)應(yīng)用的Spring上下對(duì)象WebApplicationContext作為屬性(以ROOT\_WEB\_APPLICATION\_CONTEXT\_ATTRIBUTE為鍵)放在ServletContext中 -> 因而web容器可以通過(guò)ServletContext實(shí)例獲取到Spring上下文對(duì)象
Spring中分別提供了用于啟動(dòng)WebApplicationContext的Servlet或web容器監(jiān)聽(tīng)器:
org.springframework.web.context.ContextLoaderServlet
org.springframework.web.context.ContextLoaderListener
參考: