涉及的相关类的解释
EntityResolver
学过设计模式的看到这个图应该会联想到某些设计模式,其实就是
委派模式
。
委派模式中的3个参与角色:
EntityResolver
:抽象任务角色
DelegateEntityResolver
:委派者角色
,负责决策,调用哪个具体任务角色的方法BeansDtdResolver
和PluggableSchemaResolver
:具体任务角色
,真正用于执行任务的角色
抽象接口
resolveEntity
有2个参数,publicId
和systemId
public interface EntityResolver {
public abstract InputSource resolveEntity (String publicId,
String systemId)
throws SAXException, IOException;
}
对于XSD头部而言
- publicId = null
- systemId = http://www.springframework.org/schema/beans/spring-beans.xsd
<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">
</beans>
对于DTD头部声明而言
- publicId = -//SPRING//DTD BEAN//EN
- systemId = http://www.springframework.org/dtd/spring-beans.dtd
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
DelegatingEntityResolver
public class DelegatingEntityResolver implements EntityResolver {
/** Suffix for DTD files. */
public static final String DTD_SUFFIX = ".dtd";
/** Suffix for schema definition files. */
public static final String XSD_SUFFIX = ".xsd";
//具体任务角色
private final EntityResolver dtdResolver;
private final EntityResolver schemaResolver;
//采用默认的解析器
public DelegatingEntityResolver(@Nullable ClassLoader classLoader) {
this.dtdResolver = new BeansDtdResolver();
this.schemaResolver = new PluggableSchemaResolver(classLoader);
}
//自定义解析器
public DelegatingEntityResolver(EntityResolver dtdResolver, EntityResolver schemaResolver) {
Assert.notNull(dtdResolver, "'dtdResolver' is required");
Assert.notNull(schemaResolver, "'schemaResolver' is required");
this.dtdResolver = dtdResolver;
this.schemaResolver = schemaResolver;
}
//决策使用哪个解析器进行解析
@Override
@Nullable
public InputSource resolveEntity(@Nullable String publicId, @Nullable String systemId)
throws SAXException, IOException {
if (systemId != null) {
if (systemId.endsWith(DTD_SUFFIX)) {
return this.dtdResolver.resolveEntity(publicId, systemId);
}
else if (systemId.endsWith(XSD_SUFFIX)) {
return this.schemaResolver.resolveEntity(publicId, systemId);
}
}
return null;
}
}
需求及划分
总体需求一:对各种各样的资源文件进行读取、验证,并返回资源文件的document实例
需求划分一:BeanFactory初始化过程
此处使用构造器重载给父工厂赋值了个null,是为了什么?
其实就是为了实现:若不传父工厂参数则默认为null,不需玩家手动填null
public XmlBeanFactory(Resource resource) throws BeansException {
this(resource, null);
}