深入理解Tomcat(六)Digester组件 digester和rule
它是用于解析xml文件的类库。
我们提到Digester其实有两种:
org.apache.tomcat.util.digester.Digester
maven
依赖的digester
。第一种其实只是把第二种的源代码拷贝过去了,其实基本是等同的。
市面上有两种解析方式的xml Parser。
Dom4j
sax
Digester是第二种,底层是基于sax
的。public void addObjectCreate(String pattern, String className, String attributeName)
增加对象创建规则,当匹配到pattern模式时,如果指定了attributeName,则根据attributeName创建类对象;否则根据className创建类对象。 比如对于xml里有标签
<School name="Jen">
代码中有
digester.addObjectCreate("School", School.class.getName(), "className");
则解析器会先查看<School>
标签里是否有className
属性,如果有,则用它的字符串所指向的类来构建对象。如果没有,则用School.class.getName()
所指向的类来构建对象。
此处标签显然没有指定className
,因此会用School.class.getName()
来构建对象,也就是构建School.class
。
如果代码中为
digester.addObjectCreate("School", null, "className");
说明在标签内必须显式指定className
属性,比如<School className="xxx.xx.xx.School">
,否则会报错。
digester.addSetProperties("School");
这个比较好理解。
将指定节点的属性映射到对象,即将School节点的name的属性映射到School.java。会调用属性对应的set
方法,因此必须提供。
比如,对于如下标签:
<School name="Jen">
会调用节点对象的setName
方法。
public void addSetNext(String pattern, String methodName, String paramType)
增加设置下一个规则,当匹配到pattern模式时,调用父节点的methodName方法,paramType为方法传入参数的类型
digester.addSetNext("School", "setSchool", School.class.getName());
会调用父节点的setSchool
方法,且参数类型为School.class.getName()
所指向的类,传入参数为当前节点所构建的对象。
查看源码,发现addSetProperties
、addSetNext
这些其实内部都是调用了addRule(pattern, new SetPropertiesRule());
。
所以addRule是提供一个实现了某些方法的Rule
类。
Rule抽象类有核心的几个公共方法,如下:
digester.addRuleSet(new NamingRuleSet("Server/GlobalNamingResources/"));
碰到Server/GlobalNamingResources/
节点时将会调用 org.apache.catalina.startup.NamingRuleSet
类中的 addRuleInstances
方法添加解析规则。
Digester会用流的方式解析xml,并生成对应的对象。