當(dāng)我們?cè)诜蟬pring schema的xml中配置了我們定義的javaBean,spring就可以將bean裝載到spring容器當(dāng)中。那么這中間經(jīng)歷了哪些過(guò)程呢,一起來(lái)看一下
<?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.xsd">
<bean id="person" class="com.liyl.study.java.bean.Person" />
</beans>
/**
* description: java bean
* auther: liyonglong
* date: 2020/9/6
*/
public class Person {
private Long id;
private Byte gender;
public Person() {
System.out.println("每一個(gè)人都會(huì)經(jīng)歷出生");
}
}
public class Entrance {
public static void main(String[] args) {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring/spring_bean.xml");
Person person = applicationContext.getBean(Person.class);
}
}
下圖為主要脈絡(luò):
通過(guò)資源Resource相關(guān)類(lèi)讀取資源,然后解析為BeanDefinition類(lèi)描述信息,最后注冊(cè)到Spring容器當(dāng)中

先來(lái)認(rèn)識(shí)Resource
Resource講解
Resource家族,實(shí)現(xiàn)了對(duì)不同資源的訪問(wèn)策略

AbstractResource實(shí)現(xiàn)了接口Resource中定義的大部分對(duì)資源文件的通用處理方法

Spring通過(guò)給定的文件路徑就能夠返回對(duì)應(yīng)的Resource實(shí)現(xiàn)類(lèi),比如Ant通配符。classpath、file等前綴,這歸功于ResourceLoader,里面定義了getResource()方法和getClassLoader()方法

ResourceLoader家族

那么,ResourceLoader和Spring容器會(huì)有一個(gè)什么樣的聯(lián)系呢,請(qǐng)看下圖,
上下文ApplicationContext繼承了ResourcePatternResolver,而ResourcePatternResolver正是ResourceLoader的子接口,這也是為什么我們能通過(guò)ClassPathXmlApplicationContext就可以讀取到資源文件并進(jìn)行解析。
ResourcePatternResolver用來(lái)解析classpath*前綴的路徑的,具體實(shí)現(xiàn)由實(shí)現(xiàn)類(lèi)PathMatchingResourcePatternResolver實(shí)現(xiàn)。


ResourceLoader的使用者 - - BeanDefinitionReader
BeanDefinitionReader正是使用ResourceLoader讀入資源文件并解析成BeanDefinition實(shí)例,然后注冊(cè)到容器當(dāng)中。
先來(lái)看接口定義,主要就是getBeanClassLoader讀取輸入流,然后就是loadBeanDefinitions的各個(gè)重載方法

BeanDefinitionReader家族譜
通過(guò)xml方式配置,著重關(guān)注XmlBeanDefinitionReader實(shí)現(xiàn)

首先,由AbstractBeanDefinitionReader的實(shí)現(xiàn)中獲取ResourceLoader實(shí)例
然后,通過(guò)不同的ResourceLoader實(shí)例去執(zhí)行不同的loadBeanDefinitions()方法,通常都是ResourcePatternResolver,上面說(shuō)過(guò),他是加載多個(gè)資源文件的,解析classpath*前綴的路徑就是使用這個(gè)實(shí)現(xiàn)。然后一路點(diǎn)進(jìn)去就會(huì)進(jìn)入XmlBeanDefinitionReader實(shí)現(xiàn)的loadBeanDefinitions方法
如圖
-
獲取ResourceLoader實(shí)例
2.執(zhí)行l(wèi)oadBeanDefinitions方法,這是個(gè)抽象方法,需要子類(lèi)實(shí)現(xiàn)
XmlBeanDefinitionReader中的doLoadBeanDefinitions方法就是真正的解析xml的方法,會(huì)將xml文件流解析成Document對(duì)象,然后將Document對(duì)象解析成BeanDefinition進(jìn)行注冊(cè)

解析為Document對(duì)象,然后由registerBeanDefinitions方法去解析Document

解析Document

進(jìn)入這里,繼續(xù)進(jìn)入方法,去解析document對(duì)象

然后就進(jìn)入到這里




