在Spring中的bean是最核心的东西,因为Spring就像是一个大水桶,bean就像是容器中的水,水桶如果脱离了水那么就没有什么意义了。
package container;
public class MyTestBean {
private String testStr = "testStr";
public String getTestStr() {
return testStr;
}
public void setTestStr(String testStr) {
this.testStr = testStr;
}
}
一个简单的JavaBean对象没有任何特别之处,的确,Spring的目的就是让我们的bean能成为一个纯粹的POJO。
<?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="myTestBean" class="container.MyTestBean" />
</beans>
上面的配置中可以看到bean的声明方式,尽管Spring中bean的元素定义着N种属性来支持我们的业务的各种应用,但是我们只要声明成这种样子就基本能满足我们大多数应用了
package container;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
public class BeanFactoryTest {
@Test
public void testSimpleLoad() {
BeanFactory bf = new XmlBeanFactory(new ClassPathResource("container/BeanFactoryTest.xml"));
MyTestBean bean = (MyTestBean) bf.getBean("myTestBean");
assertEquals("testStr", bean.getTestStr());
}
}
上面这段代码应该是Spring框架的最基本功能,那么这样一句简单的代码都执行了什么样的逻辑呢?可以简单的理解为这几点:
1、读取配置文件BeanFactoryTest.xml
2、根据BeanFactoryTest.xml中的配置找到对应的类配置并实例化
3、调用实例化后的实例

ConfigReader用于读取及验证配置文件,我们要用配置文件里面的东西,首先要做的是读取,然后放到内存中
ReflectionUtil用于根据配置文件中的配置进行反射实例化
App用于完成整个逻辑的串联
按照最原始的思维方式,整个过程无非如此,但是作为一个风靡世界的优秀源码当然不止这么简单
工程搭建
首先找到上一篇文章中编译好的spring-framework源码,导入spring-beans项目

这里导入spring-beans项目后报错,缺失spring-core模块,解决办法:导入spring-core项目到eclipse中。错误消失

引入依赖消除掉错误后,终于可以看到源码了,可以看到spring居然用了N多的代码实现了这个看似简单的功能,那么这些代码都是做什么的呢?我们继续深入。
Spring的结构组成
beans包的层级结构:
src/main/java:用于展现Spring的主要逻辑
src/main/resources:用于存放系统的配置文件
src/test/java:用于对主要逻辑进行单元测试
src/test/resources:用于存放测试用的配置文件
核心类介绍
DefaultListableBeanFactory
XmlBeanFactory继承自DefaultListableBeanFactory,而DefaultListableBeanFactory是整个bean加载的核心部分,是Spring注册及加载bean的默认实现。XmlBeanFactory中使用了自定义的XML读取器XmlBeanDefinitionReader,实现了个性化的BeanDefinitionReader读取,DefaultListableBeanFactory继承了AbstractAutowireCapableBeanFactory并实现了ConfigurableListableBeanFactory以及BeanDefinitionRegistry接口

从上面类图以及层次结构图中,可以很清楚地从全局角度了解DefaultListableBeanFactory的脉络,下面简单介绍一下上面类图中各个类的作用AliasRegistry:
定义对alias的简单增删改差等操作SimpleAliasRegistry:
主要使用map作为alias的缓存,并对接口AliasRegistry进行实现SingletonBeanRegistry:
定义对单例的注册及获取BeanFactory:
定义获取bean及bean的各种属性DefailtSingletonBeanFactory:
对接口SingletonBeanRegistry各函数的实现HierarchicalBeanFactory:
继承BeanFactory,也就是在BeanFactory定义的功能的基础上增加了对parentFactory的支持BeanDefinitionRegistry:
定义对BeanDefinition的各种增删改差操作FactoryBeanRegistrySupport:
在DefaultSingletonBeanRegistry基础上增加了对FactoryBean的特殊处理功能ConfigurableBeanFactory:
提供配置Factory的各种方法ListableBeanFactory:
根据各种条件获取bean的配置清单AbstractBeanFactory:
综合FactoryBeanRegistrySupport和ConfigurableBeanFactory的功能AutowireCapableBeanFactory:
提供创建bean、自动注入、初始化以及应用 bean的后处理AbstractAutowireCapableBeanFactory:
综合AbstractBeanFactory并对接口AutowireCapableBeanFactory进行实现ConfigurableListableBeanFactory:
BeanFactory配置清单,指定忽略类型及接口等DefaultListableBeanFactory:
综合上面所有功能,主要是对Bean注册后的处理
XmlBeanFactory对DefaultListableBeanFactory类进行了扩展,主要用于从XML文档中读取BeanDefinition,对于注册及获取Bean都是从父类DefaultListableBeanFactory继承的方法去实现,唯独与父类不同的个性化实现就是增加了XmlBeanDefinitionReader类型的reader属性,在XmlBeanFactory中主要使用reader属性对资源文件进行读取和注册
XmlBeanDefinitionReader
Xml配置文件的读取时Spring中重要的功能,因为Spring的大部分功能都是以配置作为切入点的,我们可以从XmlBeanDefinitionReader中梳理一下资源文件的读取、解析及注册的大致脉络,首先我们看看各个类的功能
ResourceLoader:定义资源加载器,主要应用于根据给定的资源文件地址返回对应的Resource
BeanDefinitionReader:主要定义资源文件读取并转化为BeanDefinition的各个功能
EnvironmentCapable:定义获取Environment方法
DocumentLoader:定义从资源文件加载到转换为Document的功能
AbstractBeanDefinitionReader:对EnvironmentCapable、BeanDefinitionReader:类定义的功能进行实现。
BeanDefinitionDocumentReader:定义读取Document并主持BeanDefinition功能
BeanDefinitionParserDelegate:定义解析Eliment的各种方法
经过以上分析,大致可以梳理出整个xml配置文件读取的流程

1、通过继承自AbstractBeanDefinitionReader中的方法,来使用ResourceLoader将资源文件路径转换为对应的Resource文件
2、通过DocumentLoader对Resource文件进行转换,将Resource文件转换为Document文件
3、通过实现接口BeanDefinitionDocumentReader的DefaultBeanDefinitionDocumentReader类对Document进行解析,并使用BeanDefinitionParserDelegate对Element进行解析
评论列表(2条)
刚刚学到spring,总结的很好!:stuck_out_tongue_winking_eye:
@有梦想的人不睡觉:加油哦