赞
踩
Core:Container为核心容器,包含有Core、Beans、Context和Expression Language模块。
其中,Core模块和Bean模块是Spring框架的基础部分,主要实现了控制反转(IOC)的依赖注入(DI)功能。
(1)Core模块主要包含Spring框架基本核心工具,Spring的其他组件都要用到这个包里的工具类。
(2)Beans模块是所有应用都要应用到的,包含访问和配置文件、创建和管理bean以及进行 Inversion of Control/Dependency Injection(Ioc/DI)操作。
(3)Context模块构建与Core和Beans模块基础之上,提供了一种类似于JNDI的注册器框架式的对象访问方法。Context继承了Beans的特性,为Spring核心提供了大量扩展,添加了国际化、时间传播、资源加载和对Context的透明创建的支持。
(4)Expressionn Languag模块提供了强大的表达式语言,用于在运行时查询和操作对象。
w3school中这样描述:https://www.w3cschool.cn/tomcat/4xy31k9e.htmlJNDI提供了一种统一的方式,可以用在网络上查找和访问服务。通过指定一个资源名称,该名称对应于数据库或命名服务中的一个记录,同时返回数据库连接建立所必须的信息。其实说白了JNDI就是提供一种映射。通过资源名映射到实际的配置。
Data Access/Integration曾包含JDBC、ORM、OXM、JMS和Transaction模块。
(1)JDBC模块提供了一个JDBC抽象层,封装了Spring对JDBC进行数据访问的所有类。
(2)ORM为对象关系映射层。
(3)JMS模块主要包含了一些制造和消费消息的特性。
(4)Transcation模块支持编程和声明式事务管理,这些事务类必须实现特定的接口,并且对所有的POJO透明。
Web模块是建立在应用程序上下文模块之上,为基于Web的应用程序提供了上下文,提供了基础的面向Web的集成特性。例如,文件上传等。
AOP模块提供了一个符合AOP联盟标准的面向切面编程的实现,它可以让你在任何地方定义拦截器和切点。
Test模块支持使用JUit和TestNG对Spring组件进行测试。
在正式开始之前先来看看Bean的两个核心类介绍DefaultListableBeanFactory和XmlBeanDefinitioReader。
XmlBeanFactory继承自DefaultListableBeanfactory,而DefaultListableBeanfactory是整个Bean加载的核心部分,是Spring注册和加载Bean的默认实现,而对于XmlBeanfactory与DefaultListableBeanfactory不同的是,XmlBeanfactory使用了自定义的XML读取器XmlBeanDefinitionReader,实现了个性能化的BeanDefinionReader读取。通过下图可以清晰的了解到DefaultListableBeanFactory的继承结构,简单的介绍下各个组件结构与功能:
(3)SingletonBeanRegistry:定义对单例的注册以及获取。
(4)BeanFactory: BeanFactory定义Bean以及各种Bean的属性。
(5)DefaultSingletonBeanRegistry:对接口SingletonBeanRegistry函数的实现。
(6)BeanDefinitionRegistry:是对BeanDefiition的各种增删改操作。
(7)FactoryBeanRegistrySupport :在DefaultSinngletonBeanRegistry基础上增加了对FactoryBean的特殊处理功能。
(8)ConfigurableBeanFactory: 提供配置Factory的各种方法。
(9)ListableBeanfactory:根据各种条件获取bean配置清单。
(10)AbstractBeanFactory:综合FactoryBeanRegistrySupport和ConnfigurableBeanFactory 的功能。
(11)AutowireCapableBeanFactory: 提供创建bean、自动注入、初始化以及应用bean后的处理器。
(12)AbstractAutowireCapableBeanFactory:综合AbstractBeanFactory并对接口Autowired Capable Beanfactory进行实现。
(13)ConfigurableListableBeanFactory: Beanfactor配置清单,制定忽略类型和接口等。
XML文件读取是Spring中重要的功能,因为Spring大部分功能都是以配置作为切入点,可以从XmlBeanDefinitionReader中梳理下资源文件的读取、解析以及注册的大致脉络,先来一张XmlBeanDefinnitionReader继承图。
1.通过继承自AbstractBeanDefinitionReader中的方法,将ResourcLoader将资源文件转化为对应的Resource文件。
2.通过对DocumentLoader对Resource文件进行转换,将Resource文件转换为Document文件。
3.通过实现接口BeanDefinitionnDocumentReader的DefaultDefinitionCocumentReader类对Document进行解析,并使用BeanDefinitionParseDelegate对Element进行解析。
SAX是什么?SAX(simple API for XML)是一种XML解析的替代方法。相比于DOM,SAX是一种速度更快,更有效的方法。它逐行扫描文档,一边扫描一边解析。而且相比于DOM,SAX可以在解析文档的任意时刻停止解析,但任何事物都有其相反的一面,对于SAX来说就是操作复杂。
XmlBeanFactory对DefaultListableBeanfactory类进行扩展,主要是从XML文档中读取BeanDefinition。
BeanFactory bf=new XmlBeanfactory(new ClassPathResource("beaFactory.xml"));
在上面代码执行过程中,首先调用ClassPathResource的构造函数来构造Resource资源文件的实例对象。这样后续的资源就可以用Resource提供各种资源服务了。当有了Resource后就可以进行XmlBeanFactory的初始化了。那么,问题来了,Resource资源是如何封装的?
Spring配置文件读取时通过ClassPathResource("beanFactoryTest.xml")
在java中,将不同来源的资源抽象成URL,通过注册不同的handler来处理不同资源读取逻辑,一般handler的类型使用不同前缀(协议,Protocol)来识别。,如“file”,"http"."jar"等,然而URL没有默认定义相对Classpath ServletContext等资源的handler,虽然可以自定义URLStreamHandler来解析特定URl前缀,比如“classpath”然而这需要了解URL机制,而且URL也没有提供基本的方法,如检查当前资源是否存在等方法。因此Spring对其内部使用到的资源 实现了自己的抽象,Resource接口封装底层资源。
Resource可以对所有资源问你件进行统一处理。至于实现,其实非常简单,以getInputStream为;例,CalssPathResource中实现方式便是通过class或者classLoader提供的底层方法进行调用。
有了Resource接口便可以对所有资源文件进行统一管理,实现方式也非常简单,如getInputStram为例,ClassPathResource的实现方式是通过class或者classloader提供的底层方法进行调用,对于FileSystemResource的实现方式更简单,直接使用FileInputStream对文件进行实例化。
了解了Spring将配置文件封装为Resource类型的实例方法后,就开始进行beanDefinition的解析过程,这里分析使用的是Resource作为构造函数对传入参数的解析过程。
this.reader.loadBeanDefinitions(resource);才是资源加载的真正实现,也是重点分析之一,来看一份时序图。首先,封装资源文件,XmlBeanDefinitionReader对参数Resource使用EncodedResource进行封装。然后,获取输入流从Resource中获取相应的InputStream并构造InputSource。最后,通过构造的InputSource实例和Resource实例继续调用函数doLoadBeanDefinitions,doloadBeanDefinition主要做了三件事。(1)获取XML文件的验证模式
(2)加载XML文件,并得到对应的Document.
(3)根据返回的Document注册Bean
3.3.1 XML文件的验证模式
(1)DTD
DTd(Document Type Definnnnition)即文档定义类型,是一种XML约束模式语言,是XML文件的验证 机制,属于XML文件组成的一部分。
(2)XSD
XML Schema(XML Schema Definition)描述了XML文件结构,可以用一个指定的XMLschema来验证某个XML文档,检查XML文档是否符合要求。
3.3.2 Document解析
经过了验证模式准备步骤就可以进行Document加载了,DocumentLoader定义了对Document解析的一些方法,具体的实现类是dafaultDocumentLoader,也是使用SAX解析。
SAX解析XML文档的套路大致都查案不多,Spring在这里没有什么特殊的地方,首先创建DocumentBuilderFactory,再通过DocumentBuilderFactory创建DocumentBuilder,进而解析inputSource来返回Document对象。
preProcessXml和postProcessXml是两个空方法,这两个方法是为子类而设计的,如果对模板模式比较熟悉的话,可以看出这就是用的模板方法。
parseBeanDefinnitionn(root,this.delegate)
Spring的XML配置有两大类Bean声明,一个是默认的,如"test" class="test.Testbean">
另一类定义是:
这两种方式的读取以及解析差别是非常大的,根节点或者子节点如果默认是自定义的,那么需要实现一些接口以及配置,对于根节点和子节点如果是默认命名空间的话则采用parseDefaultElement的方法进行解析。否则使用delegate.parsseCustomElement方法对自定义命名空间进行解析。
好了,Spring基本的功能结构和加载过程就先讲解到这,下一期接着讲讲Spring默认标签的解析过程。本文写作过程参考了郝佳大佬的《Spring源码深度解析》,非常感谢。
最近胖虎我新交了一个朋友,爆个照来给大家认识下。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。