01-spring对象的创建

01-spring对象的创建

流程图

spring的基础接口

Resource+ResourceLoader

可以看到Resoure接口下有许多的实现类,对不同的资源方法方式都有不同的加载对象

image-20210905100328839

在ResourceLoader接口中使用getResource()方法可以获取到Resource,一个明显的策略模式,根据不同的地址方式返回不同的Resoure对象。
在这里插入图片描述
真正使用策略模式的地方在AbstractApplicationContext这个类中,ResourcePatternResolver实现了ResourceLoader接口
在这里插入图片描述

BeanFactory

我们可以发现BeanFactory这个接口提供了很多获取bean的方法,那既然叫工厂,最重要的是要创建bean,创建bean的方法又是在何处定义的?

image-20210905102511418

BeanFactory接口下有诸多的接口以及抽象类:这里只是一小部分


在接口AutowireCapableBeanFactory中我们可以看到一个方法,至此bean工厂的核心创建功能才出现
在这里插入图片描述
接着又有问题出现了,不管我们是用初始的xml去配置bean,还是使用注解,spring是如何去获取这些配置信息的呢,BeanFactory以及其子接口拥有的获取bean以及创建bean的能力,那又是如何去创建的呢。我么都知道spring创建对象使用了反射,根据类的定义信息去创建出bean对象来,好下一步就是去分析,spring如何获取bean的定义信息的。

在BeanFactory接口下的实现类里有一个DefaultListableBeanFactory类可以说这个类里面存储了所有的bean定义信息,就是个档案馆

在这里插入图片描述

/**
 * Spring's default implementation of the {@link ConfigurableListableBeanFactory}
 * and {@link BeanDefinitionRegistry} interfaces: a full-fledged bean factory
 * based on bean definition metadata, extensible through post-processors.
 * 官方的注释是指:一个基于 bean 定义元数据的成熟 bean 工厂,可通过后处理器扩展。
 * 典型用法是在访问 bean 之前首先注册所有 bean 定义(可能从 bean 定义文件中读取)。 
 * 因此,按名称查找 Bean 是在本地 bean 定义表中的廉价操作,对预先解析的 bean 定义元数据对象进行操作。
 * <p>Typical usage is registering all bean definitions first (possibly read
 * from a bean definition file), before accessing beans. Bean lookup by name
 * is therefore an inexpensive operation in a local bean definition table,
 * operating on pre-resolved bean definition metadata objects.
 *
 */

在次类中有beanDefinitionMap这样一个map记录了根据bean名字以及bean定义信息的集合,同时为了方便获取还记录名称集合,单例集合等

image-20210905104448704

在这里插入图片描述

我们接下来看一看BeanDefinition为何物

BeanDefinition

/**
 * A BeanDefinition describes a bean instance, which has property values,
 * constructor argument values, and further information supplied by
 * concrete implementations.
 * BeanDefinition描述了一个bean实例,里面有这个实例的属性值,构造函数参数值,以及更多的由具体实现提供的信息
 * <p>This is just a minimal interface: The main intention is to allow a
 * {@link BeanFactoryPostProcessor} to introspect and modify property values
 * and other bean metadata.
 * 这只是一个最小的接口:主要目的是允许BeanFactoryPostProcessor内省和修改属性值和其他 bean 元数据。
 */

这是啥?这就是我们心心念念的bean的定义信息啊。spring容器更具这些信息可以创建出我们想要的bean对象来了。如何来的,spring解析我们xml配置文件以及注解得出来的bean的定义信息呗。

BeanDefinitionReader

解析xml、注解等解析出来的bean的配置信息,将他们解析封装到beanDefinition中

BeanDefinitionRegistry

将前一步解析出来的beanDefinition注册进入上边说的档案馆里,至此在创建bean对象前的准备工作才算完成。

  • ApplicationContext
  • Aware

debug

<?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 class="com.wh.spring.bean.Person" id="person">
		<property name="name" value="张三"/>
	</bean>

	<bean class="com.wh.spring.bean.Cat" id="cat">
		<property name="name" value="猫爷"/>
	</bean>
</beans>
/**
 * TODO
 *
 * @author wanghan
 * @date 2021/8/30 12:49
 **/
public class MainTest {
	public static void main(String[] args) {
		ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
		Person bean = context.getBean(Person.class);
		Cat cat = context.getBean(Cat.class);
		System.out.println(cat);
		System.out.println(bean);
	}
}

打入断点

DefaultListableBeanFactory类的registerBeanDefinition(String beanName, BeanDefinition beanDefinition)方法里打上断点因为只用这个方法里向bean定义信息的map里放入bean定义信息。断点到后,从堆栈信息表里看之前的方法调用

在这里插入图片描述

堆栈信息

在这里插入图片描述

读取配置文件,使用类路径下的xml

在这里插入图片描述

去刷新容器

在这里插入图片描述

创建记录bean信息以及可以创建bean对象的bean工厂

在这里插入图片描述

刷新bean工厂

在这里插入图片描述

这个创建了存储的档案馆,并将其返回组合进入容器

在这里插入图片描述

档案馆建好后要去解析配置文件了

在这里插入图片描述

获取传入的配置文件集合,这里可以发现配置文件xml是可以传多个的,使用的是数组去接受

在这里插入图片描述

开始循环解析每个配置文件里的内容

在这里插入图片描述

在这里插入图片描述

解析得到配置文件解析出的resource

在这里插入图片描述

image-20210905111513681

在这里插入图片描述

这里做了一个转换,将spring自己定义的Reource转换成了java的InputStreamSource 适配器模式,对接InputStreamSource 和 spring自己的 Resource

在这里插入图片描述

spring使用了第三方jar的xml解析包,去解析xml,这里是在XmlBeanDefinitionReader里操作,即实现了BeanDefinitionReader接口的类

image-20210905113809596

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

解析出doc对象后要去解析doc内容一个一个标签去解析

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

将解析出的配装到BeanDefinitionHolder对象中

在这里插入图片描述

在此将BeanDefinitionHolder中的封装好的beanDefinition传入档案馆

在这里插入图片描述

档案馆DefaultListableBeanFactory中去添加bean定义信息

在这里插入图片描述

在这里插入图片描述

对于DefaultListableBeanFactory档案馆实现了注册、存储bean定义信息等多个接口,容器对象和他是组合关系

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值