Tomcat中使用Digester
Tomcat中Catalina一个重要功能就是读取server.xml配置文件实例化tomcat中组件。Catalina就使用了Digester技术来解析server.xml将所有组件设置实例化设置到属性对象StandardServer中
加载Catalina
public void load() {
...省略代码
/** 创建Digester实例,定义解析/conf/Server.xml文件规则**/
Digester digester = createStartDigester();
InputSource inputSource = null;
InputStream inputStream = null;
File file = null;
try {
/** 读取 catalina_home\conf\server.xml 配置文件 **/
try {
file = configFile();
inputStream = new FileInputStream(file);
inputSource = new InputSource(file.toURI().toURL().toString());
} catch (Exception e) {
if (log.isDebugEnabled()) {
log.debug(sm.getString("catalina.configFail", file), e);
}
}
...省略代码
/** 将xml解析对象放置到当前对象属性中 **/
try {
inputSource.setByteStream(inputStream);
//将当前对象Catalina实例入栈,读取xml属性将设置到Server属性对象中
digester.push(this);
digester.parse(inputSource);
} catch (SAXParseException spe) {
log.warn("Catalina.start using " + getConfigFile() + ": " +
spe.getMessage());
return;
} catch (Exception e) {
log.warn("Catalina.start using " + getConfigFile() + ": " , e);
return;
}
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
// Ignore
}
}
}
创建Digester实例
/**
* 创建并配置我们将用于启动的Digester。
* 主要用于解析server.xml
*/
protected Digester createStartDigester() {
long t1=System.currentTimeMillis();
// Initialize the digester
Digester digester = new Digester();
/** 设置为false表示解析xml时不需要进行DTD的规则校验 **/
digester.setValidating(false);
/** 是否进行节点设置规则校验,如果xml中相应节点没有设置解析规则会在控制台显示提示信息 **/
digester.setRulesValidation(true);
/** 设置无效的属性,也就是在检查到这些属性时SetProperties规则不会将其设置到规则指定对象属性中 **/
Map<Class<?>, List<String>> fakeAttributes = new HashMap<>();
List<String> objectAttrs = new ArrayList<>();
objectAttrs.add("className");
fakeAttributes.put(Object.class, objectAttrs);
// Ignore attribute added by Eclipse for its internal tracking
List<String> contextAttrs = new ArrayList<>();
contextAttrs.add("source");
fakeAttributes.put(StandardContext.class, contextAttrs);
digester.setFakeAttributes(fakeAttributes);
digester.setUseContextClassLoader(true);
/**
* 添加内置解析规则
* 规则如下
* 碰到<server>标签将默认会实例化一个org.apache.catalina.core.StandardServer
* (这里className表示如果<server>标签如果存在className属性将实例化属性值对应的对象)入栈到digester对象处理栈顶
* 碰到</server>将创建对象从digester对象处理栈中出栈
*/
digester.addObjectCreate("Server",
"org.apache.catalina.core.StandardServer",
"className");
/** 添加内置解析规则
* 规则如下
* 碰到<server>标签时会将标签中属性值映射到标签实例对象的属性中
*/
digester.addSetProperties("Server");
/** 添加内置解析规则
* 规则如下
* 碰到</server>标签时,会找到栈顶对象之后的对象调用指定方法(setServer),并将栈顶对象作为参数(指定参数类型org.apache.catalina.Server)
*
* addSetNext 本质是将子标签中解析完的对象设置到父对象属性中。
*/
digester.addSetNext("Server",
"setServer",
"org.apache.catalina.Server");
...省略代码
/** 为指定xml规则添加自定义规则 **/
digester.addRule("Server/Service/Connector",
new ConnectorCreateRule());
digester.addRule("Server/Service/Connector",
new SetAllPropertiesRule(new String[]{"executor", "sslImplementationName"}));
/** 为指定xml标签添加一组规则 **/
digester.addRuleSet(new NamingRuleSet("Server/GlobalNamingResources/"));
...省略代码
return (digester);
}
网友评论