Spring容器的基本实现

1.容器的基本用法

bean是Spring中最核心的东西,因为Spring就像是个大水桶,而bean就像是容器中的水,水桶脱离了水也便没什么用处了。
Spring的目的就是让我们的bean能成为一个纯粹的POJO,这也是Spring所追求的。

2.功能分析

bean完成的功能无非就是以下几点:
·读取配置文件
·根据配置文件中的配置找到对应的类的配置,并实例化。
·调用实例化后的实例
如果需要完成我们预想的功能,至少需要3个类。
·ConfigReader:用于读取及验证配置文件
·ReflectionUtil:用于根据配置文件中的配置进行反射实例化
·App:用于完成整个逻辑的串联。

在这里插入图片描述
最简单的Spring功能架构

3.Spring的结构组成

3.1beans包的层级结构
beans包中的各个源码包的功能如下。
·src/main/java用于展现Spring的主要逻辑。
·src/main/resources用于存放系统的配置文件。
·src/test/java用于对主要逻辑进行单元测试。
·src/test/resources用于存放测试用的配置文件。
3.2核心类介绍
1.DefaultListableBeanFactory
XmlBeanFactory继承自DefaultListableBeanFactory,而DefaultListableBeanFactory是整个bean加载的核心部分,是Spring注册及加载bean的默认实现,而对于XmlBeanFactory与DefaultListableBeanFactory不同的地方其实是在XmlBeanFactory中使用了自定义的XML读取器XmlBeanDefinitionReader,实现了个性化的BeanDefinitionReader读取,DefaultListableBeanFactory继承了AbstractAutowireCapableBeanFactory并实现了ConfigurableListableBeanFactory以及BeanDefinitionRegistry接口。
容器加载相关类:
·AliasRegistry:定义对alias的简单增删改等操作。
·SimpleAliasRegistry:主要使用map作为alias的缓存,并对接口AliasRegistry进行实现。
·SingletonBeanRegistry:定义对单例的注册及获取。
·BeanFactory:定义获取bean及bean的各种属性。
·DefaultSingletonBeanRegistry:对接口SinletonBeanRegistry各函数的实现
·HierarchicalBeanFactory:继承BeanFactory,也就是在BeanFactory定义的功能的基础上增加了对parentFactory的支持。
·BeanDefinitionRegistry:定义对BeanDefinition的各种增删改操作。
·FactoryBeanRegistrySupport:在DefaultSingletonBeanRegistry基础上增加了对FactoryBean的特殊处理功能。
·ConfigurableBeanFactory:提供配置Factory的各种方法。
·ListableBeanFactory:根据各种条件获取bean的配置清单。
·AbstractBeanFactory:综合FactoryBeanRegistrySuppirt和ConfigurableBeanFactory的功能
·AutowireCapableBeanFactory:提供创建bean、自动注入、初始化以及应用bean的后处理器。
·AbstractAutowireCapableBeanFactory:综合AbstractBeanFactory并对接口Autowire Capable BeanFactory进行实现。
·ConfigurableListableBeanFactory:BeanFactory配置清单,指定忽略类型及接口等。
·DefaultListableBeanFactory:综合上面所有功能,主要是对bean注册后的处理。
2.XmlBeanDefinitionReader
XML配置文件的读取是Spring中重要的功能,因为Spring的大部分功能都是以配置作为切入点的,那么我们可以从XmlBeanDefinitionReader中梳理一下资源文件读取、解析及注册的大致脉络,XmlBeanDefinitionReader各个类的功能如下:
·ResourceLoader:定义资源加载器,主要应用于根据给定的资源文件地址返回的Resource。
·BeanDefinitionReader:主要定义资源文件读取并转换为BeanDefinition的各个功能。
·EnvironmentCapable:定义获取Environment方法。
·DocumentCapable:定义从资源文件加载到转换为Bocument的功能。
·AbstractBeanDefinitionReader:对EnvironmentCapable、BeanDefinitionReader类定义的功能进行实现。
·BeanDefinitionDocumentReader:定义读取Docuemnt并注册BeanDefinition功能。
·BeanDefinitionParserDelegate:定义解析Element的各种方法。
XmlBeanDefinitionReader中主要包含以下几步的处理:
(1)通过继承自AbstractBeanDefinitionReader中的方法,来使用ResourLoader将资源文件路径转换为对应的Resource文件。
(2)通过DocumentLoader对Resource文件进行转换,将Resource文件转换为Document文件。
(3)通过实现接口BeanDefinitionDocumentReader和DefaultBeanDefinitionDocumentReader类对Document进行解析,并使用BeanDefinitionParserDelegate对Element进行解析。

4.容器的基础XmlBeansFactory

Resource资源是如何封装的。
(1)配置文件封装
Spring的配置文件读取是通过ClassPathResource进行封装的。
String对其内部使用到的资源实现了自己的抽象结构:Resource接口封装底层资源
InputStreamSource封装任何能返回InputStream的类,它只有一个方法定义:getInputStream(),该方法返回一个新的InputStream对象。
Resource接口抽象了所有Spring内部使用到的底层资源:File、URL、Classpath等。首先它定义了3个判断当前资源状态的方法:存在性(exists)、可读性(isReadable)、是否处于打开状态(isOpen)。另外,Resource接口还提供了不同资源到URL、URI、File类型的转换,以及获取lastModified属性、文件名的方法。为了便于操作,Resource还提供了基于当前资源创建一个相对资源的方法:createRelative()。在错误处理中需要详细地打印出错的资源文件,因而Resource还提供了getDescription()方法用来在错误处理中打印信息。
对不同资源的资源文件都有相应的Resource实现:文件(FileSystemResource)、Classpath资源(ClassPathResource)、URL资源(UrlResource)、InputStream资源(InputStreamResource)、Byte资源(ByteArrayResource)等。
有了Resource接口便可以对所有资源文件进行统一处理。
(2)加载Bean
加载Bean的整个的处理过程如下:
1.封装资源文件。当进入XmlBeanDefinitionReader后首先对参数Resource使用EncodedResource类进行封装。
2.获取输入流。从Resource中获取对应的InputStream并构造InputSource。
3.通过构造的InputSource实例和Resource实例继续调用函数doLoadBeanDefinitions
加载Bean只做了三件事,这三件事的每一件都必不可少。
·获取对XML文件的验证模式。
·加载XML文件,并得到对应的Document。
·根据返回的Document注册信息。
这3个步骤支撑着整个Spring容器部分的实现,尤其是第3步对配置文件的解析,逻辑非常的复杂。

5.获取XML的验证模式

XML文件的验证模式保证了XML文件的正确性,而比较常用的验证模式有两种:DTD和XSD。
(1)DTD与XSD区别
DTD即文档类型定义,是一种XML约束模式语言,是XML文件的验证机制,属于XML文件组成的一部分。DTD是一种保证XML文档格式正确的有效方法,可以通过比较XML文档和DTD文件来看文档是否符合规范,元素和标签使用是否正确。一个DTD文档包含:元素的定义规则,元素间关系的定义规则,元素可使用的属性,可使用的实体或符号规则。
XML Schema语言就是XSD。XML Schema描述了XML文档的结构。可以用一个指定的XML Schema来验证某个XML文档,以检查给XML文档是否符合其要求。文档设计者可以通过XML Schema指定XML文档所允许的结构和内容,并可据此检查XML文档是否有效。XML Schema本身是XML文档,它符合XML语法结构。可以用通用的XML解释器解析它。
(2)验证模式的读取
如果设定了验证模式则使用设定的验证模式(可以通过对调用XmlBeanDefinitionReader中的setValidationMode方法进行设定),否则使用自动检测的方式。
Spring用来检测验证模式的办法就是判断是否包含DOCTYPE,如果包含就是DTD,否则就是XSD。

6.获取Document

经过了验证模式准备的步骤就可以进行Document加载了,同样XmlBeanFactoryReader类对于文档读取并没有亲历亲为,而是委托给了DocumentLoader去执行。

7.解析及注册BeanDefinitions

解析及注册BeanDefinitions处理流程,首先是对profile的处理,然后进行解析。
(1)profile属性的使用
首先程序会获取beans节点是否定义了profile属性,如果定义了则会需要到环境变量中去寻找,所以这里首先断言environment不肯为空,因为profile是可以同时指定多个的,需要程序对其拆分,并解析每个profile都是符合环境变量中所定义的,不定义则不会浪费性能去解析。
(2)解析并注册BeanDefinition
如果采用Spring默认的配置,Spring当然知道该怎么做,但是如果是自定义的,那么就需要用户实现一些接口及配置了。对于根节点或者子节点如果是默认命名空间的话则采用parseDefaultElement方法进行解析,否则使用delegate.parseCustomElement方法对自定义命名空间进行解析

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值