背景
spring的配置文件一般有两种类型:DTD或者XSD类型.配置文件中配置了bean和bean依赖关系的定义,加载配置文件并解析文件中的bean定义是为容器注册和获取bean的准备工作.Spring将配置文件看成一个资源(Resource),首先会将改Resource进行编码,判断资源的验证模式validationMode(即是属于DTD验证模式还是XSD验证模式),根据对应的模式加载和解析配置文件得到Document文件.对于xml的解析交给了SAX来负责.
在解析XML文件过程中,SAX首先会读取改文档上的声明,根据声明寻找相应的DTD定义,以便对文档进行验证.默认寻找方式是从网络上下载相应的DTD声明,并进行验证.下载过程比较漫长也受网络的影响,所以spring在项目中提供了DTD声明文件(如 spring-beans-2.0.dtd). EntityResolver类的作用就是项目本身提供一个如何寻找DTD声明的方法,即有程序来实现寻找DTD声明过程,将获取到的DTD文件交给SAX,避免网络的寻找.
Spring中的EntityResolver采用了代理模式来实现,下面我会详细的介绍源码中的该代理模式设计.
源码中的设计
结构
源码实现
在spring源码设计中,1
2
3
4
5
6//定义了一个公共的 EntityResolver 接口
public interface EntityResolver {
public abstract InputSource resolveEntity (String publicId,
String systemId)
throws SAXException, IOException;
}
具体实现类,即DTD和XSD的声明寻找方式:
DTD声明的寻找方式:
1 | public class BeansDtdResolver implements EntityResolver { |
XSD声明的寻找方式:
1 | public class PluggableSchemaResolver implements EntityResolver { |
采用代理模式来进行解析,在代理内部根据验证模式选择具体的代理对象(EntityResolver)来完成具体的寻找过程.
1 | public class DelegatingEntityResolver implements EntityResolver { |