LifecycleListener listener = new ContextConfig(); ((Lifecycle) context).addLifecycleListener(listener);首先得在StandContext里注入ContextConfig这个监听器。
ContextConfig.java public void lifecycleEvent(LifecycleEvent event) { ... // Process the event that has occurred if (event.getType().equals(Lifecycle.START_EVENT)) start(); else if (event.getType().equals(Lifecycle.STOP_EVENT)) stop(); }我们看看ContextConfig的start方法。
private synchronized void start() { ... // Process the default and application web.xml files defaultConfig(); //解析conf/xml.xml applicationConfig(); //解析WEB-INF/web.xml ... }我们先不管整个tomcat的xml就看单个项目的:
private void applicationConfig() { ... // Process the application web.xml file synchronized (webDigester) { //public static final String ApplicationWebXml = "/WEB-INF/web.xml"; URL url =servletContext.getResource(Constants.ApplicationWebXml); InputSource is = new InputSource(url.toExternalForm()); is.setByteStream(stream); webDigester.setDebug(getDebug()); if (context instanceof StandardContext) { ((StandardContext) context).setReplaceWelcomeFiles(true); } webDigester.clear(); webDigester.push(context);//此时的栈里面就有context了 webDigester.parse(is); //开始解析 } ... }现在的问题是,那webDigester是怎么来的?
private static Digester createWebDigester() { ... Digester webDigester = new Digester(); ... webDigester.addRuleSet(new WebRuleSet()); //addRuleSet 对这个不清楚的看上一节 return (webDigester); }现在我们就要去看WebRuleSet类了,还记得主要看哪个方法吗?
WebRuleSet.java public void addRuleInstances(Digester digester) { .... digester.addRule(prefix + "web-app/servlet",new WrapperCreateRule(digester)); ... digester.addCallMethod(prefix + "web-app/servlet/servlet-class", "setServletClass", 0); digester.addCallMethod(prefix + "web-app/servlet/servlet-name", "setName", 0); digester.addCallMethod(prefix + "web-app/servlet-mapping", "addServletMapping", 2); //setServletClass这个方法最后在哪里调用的? 请大家自己想一想 } final class WrapperCreateRule extends Rule { public void begin(Attributes attributes) throws Exception { Context context =(Context) digester.peek(digester.getCount() - 1); Wrapper wrapper = context.createWrapper(); digester.push(wrapper); if (digester.getDebug() > 0) digester.log("new " + wrapper.getClass().getName()); } }
web-app/servlet/servlet-name 碰到这个后,调用wrapper的那个方法就ok。