当我们在符合spring schema的xml中配置了我们定义的javaBean,spring就可以将bean装载到spring容器当中。那么这中间经历了哪些过程呢,一起来看一下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | <?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("每一个人都会经历出生"); } } public class Entrance { public static void main(String[] args) { ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring/spring_bean.xml"); Person person = applicationContext.getBean(Person.class); } } |
下图为主要脉络:
通过资源Resource相关类读取资源,然后解析为BeanDefinition类描述信息,最后注册到Spring容器当中
先来认识Resource
Resource讲解
Resource家族,实现了对不同资源的访问策略
AbstractResource实现了接口Resource中定义的大部分对资源文件的通用处理方法
Spring通过给定的文件路径就能够返回对应的Resource实现类,比如Ant通配符。classpath、file等前缀,这归功于ResourceLoader,里面定义了getResource()方法和getClassLoader()方法
ResourceLoader家族
那么,ResourceLoader和Spring容器会有一个什么样的联系呢,请看下图,
上下文ApplicationContext继承了ResourcePatternResolver,而ResourcePatternResolver正是ResourceLoader的子接口,这也是为什么我们能通过ClassPathXmlApplicationContext就可以读取到资源文件并进行解析。
ResourcePatternResolver用来解析classpath*前缀的路径的,具体实现由实现类PathMatchingResourcePatternResolver实现。
ResourceLoader的使用者 - - BeanDefinitionReader
BeanDefinitionReader正是使用ResourceLoader读入资源文件并解析成BeanDefinition实例,然后注册到容器当中。
先来看接口定义,主要就是getBeanClassLoader读取输入流,然后就是loadBeanDefinitions的各个重载方法
BeanDefinitionReader家族谱
通过xml方式配置,着重关注XmlBeanDefinitionReader实现
首先,由AbstractBeanDefinitionReader的实现中获取ResourceLoader实例
然后,通过不同的ResourceLoader实例去执行不同的loadBeanDefinitions()方法,通常都是ResourcePatternResolver,上面说过,他是加载多个资源文件的,解析classpath*前缀的路径就是使用这个实现。然后一路点进去就会进入XmlBeanDefinitionReader实现的loadBeanDefinitions方法
如图
-
获取ResourceLoader实例
2.执行loadBeanDefinitions方法,这是个抽象方法,需要子类实现
XmlBeanDefinitionReader中的doLoadBeanDefinitions方法就是真正的解析xml的方法,会将xml文件流解析成Document对象,然后将Document对象解析成BeanDefinition进行注册
解析为Document对象,然后由registerBeanDefinitions方法去解析Document
解析Document
进入这里,继续进入方法,去解析document对象
然后就进入到这里