Spring源码解析(一)- 容器的基本实现

Spring源码解析(一)- 容器的基本实现,第1张

       Spring使用 基本的JavaBean 来完成以前只可能由EJB完成的事情,是个分层架构。Spring创建bean都需要通过 读取 、 解析 、 校验配置文件, 然后注册创建成Bean。 Spring是一个Bean容器 , 主要作用是替我们管理bean对象 (简单的Java类对象的生命周期)。不管框架如何强大,还是需要我们程序员来告诉其一些必要信息的(比如要 管理的bean对象的类相关信息、是否开启组件扫描 等),这些我们称之为对 Spring框架的配置 ,目前主流的配置方式是 通过使用配置文件或注解。

        Spring中最核心的两个类: DefaultListableBeanFactory、XmlBeanDifinitionReader。DefaultListableBeanFactory 是整个bean加载的核心部分,是Spring注册及加载bean的默认实现 。XmlBeanDefinitionReader 主要使用reader属性对资源文件进行读取和注册。

        XML配置文件读取是Spring中重要的功能,大部分Spring大部分功能都是 以配置作为切入点 。 XmlBeanFactory 继承自 DefaultListableBeanFactory ,而对于 DefaultListableBeanFactory 不同的地方其实是在 XmlBeanFactory 中使用了自定义的XML读取器 XmlBeanDefinitionReader ,主要用于从XML文档中读取 BeanDefinition, 实现了个性化的 BeanDefinitionReader 读取, DefaultListableBeanFactory 继承了 AbstractAutowireCapableBeanFactory 并实现了 ConfigurableListableBeanFactory 以及 BeanDefinitionRegistry 接口。

        Spring的配置文件读取是通过ClasaPathResource进行封装的 ,如:new ClassPathResource("beanxml")。在java中, 将不同来源的资源的读取逻辑抽象成URL ,通过注册不同的 handler来处理。 一般handler的类型使用不同的前缀,URL没有默认定义相对的path路径,也 没有提供相关方法对资源进行检查 ,顾Spring对其内部需要使用到的资源做了属于自己的抽象结构, 用Resource接口来封装底层资源。

        Resource 接口继承 InputStreamSource(封装了任何能返回InputStream的类)。

        Resource接口抽象了所有Spring内部使用到的底层资源 ,首先它定义了3个能判断当前资源状态的方法: 存在性(exists)、可读性(isReadable)、是否处于打开状态(isOpen) 。有了Resource接口便可以对所有资源进行统一处理。 ClassPathResource 中的实现是通过class或 classLoader 提供的底层方法进行调用。以此完成对配置文件资源的封装。

        当通过Resource相关类完成了对配置文件进行封装,接下来由 XmlBeanDefinitionReader 完成对配置文件的读取工作。

       XML文件的验证模式有两种:DTD、XSD(XML Schema)

        DTD即文档类型定义, 是一种XML约束模式语言,是XML文件的验证机制 。是一种保证XML文档格式正确的有效方法, 可以通过比较XML文档和DTD文件来查看文档是否符合规范,元素和标签的使用是否正确 。一个DTD文档包含:元素的定义规则、元素间关系的定义规则、元素可使用的属性、可使用的实体或符号规则。 要使用DTD验证模式需要在XML文件的头部声明。

        XML Schema语言就是XSD。   XML Schema描述了XML文档的结构。可以用一个指定的XML Schema来验证某个XML文档,以检查该XML文档是否符合其要求。也可以 通过XML Schema指定一个XML文档所允许的结构和内容 。XML Schema本身也是一个XML文档,符合XML语法结构,可以用通用的XML解析器解析它。    

        使用XML Schema文档对XML实例进行校验,要声明名称空间和指定该名称空间所对应的XML Schema文档存储位置 。通过schemaLocation属性来指定名称空间所对应的XML Schema文档的存储地址(1、名称空间URL;2、该名称空间所标识的XML Schema文件地址或URL地址)。

      另外验证模式通过 XmlBeanDefinitionReader 中的setValidationMode方法进行设定。而 Spring 用来检测验证模式的方法实际上就是判断是否包含 DOCTYPE ,如果包含就是 DTD ,否则就是 XSD 。

        XML文件经过验证模式,交由DocumentLoader进行解析成对应的 Document。 而解析的过程中存在这么一环节:(EntityResolver) 根据声明去寻找对应的DTD定义,以便对文档进行验证认证 。也可以通过setEntityResolver设置DTD定义。EntityResolver它用来接收两个参数publicId和systemId,xsd格式文件通常publicId为null。而对于不同的验证模式采用不同的解析器进行解析,并把文件转换成Document文件,用于提取及注册bean。

          Document 文件通过 BeanDefinitionDocumentReader 进行内部逻辑处理,并提取root用于作为参数继续完成BeanDefinition的注册。

1基于XML的定时器

11 Spring的XML文件片段内容

方法1:

<!-- 定时器开关-->

<task:scheduled-tasks>

         <!-- 定时任务(可以有多个定时任务),和执行时间,每5秒执行一次  -->

          <task:scheduled ref="myTask" method="printSomeThing" cron="/5 "></>

</ task:scheduled-tasks >

<!-- 定时任务Bean所在位置 -->

<context:component-scan base-package="comyuxiSofterwaretask"/>

方法2:

<bean id="demoTask" class="comyuxiSofterwaretaskDemoTask"/>

<bean id="BuildTask" class="orgspringframeworkschedulingquartzMethodInvokingJobDetailFactoryBean">

<property name="targetObject" ref="demoTask"/>

<property name="targetMethod" value="printSomeThing" />

<property name="concurrent" value="false" />

</bean>

<bean id="BuildTrigger" class="orgspringframeworkschedulingquartzCronTriggerBean">

<property name="jobDetail" ref="BuildTask"/>

<property name="cronExpression" value="0/5 0 " />

</bean>

12 Bean类片段内容

package comyuxiSofterwaretask;

/

  基于XML的Spring定时器

@author yuxiSofterware

/

public class DemoTask {

public void printSomeThing() {

          Systemoutprintln("XML定时器触发。");

}

}

13 编写main方法,解析Spring的XML文件,定时器就会按时触发,编写过程略。

2 基于注解的Spring定时器

package comyuxiSofterwaretask;
import orgspringframeworkschedulingannotationScheduled;
import orgspringframeworkstereotypeComponent;

/

基于注解的Spring定时器

@author yuxiSofterware

/

@Component

public class DemoTask {

 /

  定时任务,每五秒钟执行一次

 /

@Scheduled(corn=" /5 ")

public voidprintSomeThing() {

Systemoutprintln("XML定时器触发。");

}

}

3 关于定时器,定时任务时间的说明

定时表达式的格式:秒 分 时 日 月 周 年(可选)。
字段名                 允许的值                        允许的特殊字符

秒                         0-59                               , - /

分                         0-59                               , - /

小时                   0-23                               , - /

日                         1-31                               , - / L W C

月                         1-12 or JAN-DEC          , - /

周几                     1-7 or SUN-SAT            , - / L C #

年 (可选字段)     empty, 1970-2099      , - /

“”字符:表示不确定的值

“,”字符:指定数个值

“-”字符:指定一个值的范围

“/”字符:指定一个值的增加幅度。n/m表示从n开始,每次增加m

“L”字符:用在日表示一个月中的最后一天,用在周表示该月最后一个星期X

“W”字符:指定离给定日期最近的工作日(周一到周五)

“#”字符:表示该月第几个周X。6#3表示该月第3个周五

你好,mybatis是解析xml的过程如下
这里是用mybatis-spring的SqlSessionFactoryBean当作的入口
1解析spring的配置
不过很多参数都是spring中来处理了,所以mybatis-spring没有先parse而是先加载了配置文件
依次是
typeAliasesPackage
typeAliases
Plugins
typeHandlersPackage
typeHandlers
typeAliases
相当于加载了上面的typeAliases,plugins,typeHandlers
然后typeAliases put到TYPE_ALIASES供查询时调用类型转换
Plugins
拦截器也private final List<Interceptor> interceptors = new ArrayList<Interceptor>();
这里用的ArrayList所以是自顶向下按照顺序执行的
typeHandlers
Typehandler 也是put到private final Map<Class<>, Map<JdbcType, TypeHandler>> TYPE_HANDLER_MAP = new
HashMap<Class<>, Map<JdbcType, TypeHandler>>();到时候使用

[TOC]
date [2019-8-15]

Spring中在外部看来,是通过XMLBeanDefinitionReader来完成Bean定义的加载、解析、以及Bean定义的注册,但是XMLBeanDefinitionReader其底层维护了多个组件来完成上面的每一件事情,这很好地体现了单一职责的设计。而DefaultDocumentLoader这个组件,就是完成Bean定义的加载功能。

DefinitionDocumentReader 只有一个实现类DefaultBeanDefinitionDocumentReader

在loadDocument方法中涉及一个参数EntityResolver。
EntityResolver的作用是项目本身就可以提供一个如何寻找DTD声明的方法,由程序来实现寻找DTD声明的过程,比如将DTD文件放到
项目某处,在实现时直接将此文档读取并返回给SAX。避免通过网络来寻找相应的声明。
EntityResolver接口声明如下:


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/13398781.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-07-28
下一篇 2023-07-28

发表评论

登录后才能评论

评论列表(0条)

保存