if (getServer() == null) {
load();
}
if (getServer() == null) {
log.fatal("Cannot start server. Server instance is not configured.");
return;
}
long t1 = System.nanoTime();
// Start the new server
try {
getServer().start();
} catch (LifecycleException e) {
log.error("Catalina.start: ", e);
}
//addObjectCreate所使用的规则ObjectCreateRule的begin方法
public void begin(String namespace, String name, Attributes attributes)
throws Exception {
// Identify the name of the class to instantiate
String realClassName = className;
if (attributeName != null) {
String value = attributes.getValue(attributeName);
if (value != null) {
realClassName = value;
}
}
if (digester.log.isDebugEnabled()) {
digester.log.debug("[ObjectCreateRule]{" + digester.match +
"}New " + realClassName);
}
if (realClassName == null) {
throw new NullPointerException("No class name specified for " +
namespace + " " + name);
}
// Instantiate the new object and push it on the context stack
Class<!--?--> clazz = digester.getClassLoader().loadClass(realClassName);
Object instance = clazz.newInstance();
digester.push(instance);
}
//addSetNext所使用的规则SetNextRule的end方法
public void end(String namespace, String name) throws Exception {
// Identify the objects to be used
Object child = digester.peek(0);
Object parent = digester.peek(1);
if (digester.log.isDebugEnabled()) {
if (parent == null) {
digester.log.debug("[SetNextRule]{" + digester.match +
"} Call [NULL PARENT]." +
methodName + "(" + child + ")");
} else {
digester.log.debug("[SetNextRule]{" + digester.match +
"} Call " + parent.getClass().getName() + "." +
methodName + "(" + child + ")");
}
}
// Call the specified method
IntrospectionUtils.callMethod1(parent, methodName,
child, paramType, digester.getClassLoader());
}
//SetPropertiesRule的begin方法比较长就不贴出.
上述代码是addObjectCreate和addSetNext所使用规则的主要起作用的方法,通过代码很容易看出addObjectCreate的作用就是Instantiate the new object and push it on the context stack而addSetNext的作用就是调用栈顶第一个元素的方法并把栈顶元素传入.
有了对Digester的了解,想要从配置文件Server.xml中探寻Catalina初始化Server,及之中组件的关系就不是什么难事了.