web.xml监听器的配置的解析->监听器的实例化->监听器的调用
// web.xml监听器的配置的解析、监听器的实例化、监听器的调用
org.apache.catalina.core.StandardContext{
protected synchronized void startInternal() throws LifecycleException {
// 解析上下文的web.xml文件
fireLifecycleEvent(Lifecycle.CONFIGURE_START_EVENT, null); // 触发事件 "configure_start"-------
// 监听器的实例化、监听器的调用
if (!listenerStart()) {
log.error(sm.getString("standardContext.listenerFail"));
ok = false;
}
}
// 监听器的实例化、监听器的调用
public boolean listenerStart() {
// Instantiate the required listeners
String listeners[] = findApplicationListeners(); // <listener></listener>
Object results[] = new Object[listeners.length];
boolean ok = true;
for (int i = 0; i < results.length; i++) {
String listener = listeners[i];
results[i] = getInstanceManager().newInstance(listener); // 创建监听器对象
}
// Sort listeners in two arrays 把监听器分组
ArrayList<Object> eventListeners = new ArrayList<>();
ArrayList<Object> lifecycleListeners = new ArrayList<>();
for (int i = 0; i < results.length; i++) {
if ((results[i] instanceof ServletContextAttributeListener)
|| (results[i] instanceof ServletRequestAttributeListener)
|| (results[i] instanceof ServletRequestListener)
|| (results[i] instanceof HttpSessionIdListener)
|| (results[i] instanceof HttpSessionAttributeListener)) { // 事件监听器
eventListeners.add(results[i]);
}
if ((results[i] instanceof ServletContextListener)
|| (results[i] instanceof HttpSessionListener)) { // 生命周期监听器
lifecycleListeners.add(results[i]);
}
}
for (Object eventListener: getApplicationEventListeners()) {
eventListeners.add(eventListener);
}
setApplicationEventListeners(eventListeners.toArray());
for (Object lifecycleListener: getApplicationLifecycleListeners()) {
lifecycleListeners.add(lifecycleListener);
if (lifecycleListener instanceof ServletContextListener) {
noPluggabilityListeners.add(lifecycleListener);
}
}
setApplicationLifecycleListeners(lifecycleListeners.toArray());
// Ensure context is not null
getServletContext();
context.setNewServletContextListenerAllowed(false);
Object instances[] = getApplicationLifecycleListeners(); // 生命周期监听器
if (instances == null || instances.length == 0) {
return ok;
}
ServletContextEvent event = new ServletContextEvent(getServletContext());
ServletContextEvent tldEvent = null;
if (noPluggabilityListeners.size() > 0) {
noPluggabilityServletContext = new NoPluggabilityServletContext(getServletContext());
tldEvent = new ServletContextEvent(noPluggabilityServletContext);
}
for (int i = 0; i < instances.length; i++) { // 触发“生命周期监听器”
if (!(instances[i] instanceof ServletContextListener))
continue;
ServletContextListener listener =
(ServletContextListener) instances[i];
try {
fireContainerEvent("beforeContextInitialized", listener);
if (noPluggabilityListeners.contains(listener)) {
listener.contextInitialized(tldEvent);
} else {
listener.contextInitialized(event);
}
fireContainerEvent("afterContextInitialized", listener);
} catch (Throwable t) {
ExceptionUtils.handleThrowable(t);
fireContainerEvent("afterContextInitialized", listener);
getLogger().error
(sm.getString("standardContext.listenerStart",
instances[i].getClass().getName()), t);
ok = false;
}
}
return (ok);
}
}
// 解析上下文的web.xml文件
class org.apache.catalina.startup.ContextConfig{
public void lifecycleEvent(LifecycleEvent event) {
context = (Context) event.getLifecycle(); // 取得触发者 org.apache.catalina.core.StandardContext
if (event.getType().equals(Lifecycle.CONFIGURE_START_EVENT)) { // "configure_start"
configureStart();
}
}
// 配置启动事件 "configure_start"-------
protected synchronized void configureStart() {
// 读取并解析“d:/a/c/d/tomcat/conf/web.xml”,读取并解析"d:/a/b/tomcat/conf/Catalina/localhost/web.xml.default"
// 取得输入流 "d:/a/b/c/tomcat/webapps/dir1/WEB-INF/web.xml"
// 合并配置文件内容
// 合并全局配置
// 使用 org.apache.jasper.servlet.JspServlet 包装 <jsp-file>/a/b/c/file.jsp</jsp-file>的文件
// 把解析处理的内容设置到 context 中 ,如:context.addFilterMap(filterMap);
webConfig();//!!!! 核心
}
protected void webConfig() {
WebXml webXml = createWebXml();
// Parse context level web.xml
// 取得输入流 "d:/a/b/c/tomcat/webapps/dir1/WEB-INF/web.xml"
InputSource contextWebXml = getContextWebXmlSource();
if (!webXmlParser.parseWebXml(contextWebXml, webXml, false)) { // 解析文件 ,数据存入webXml
ok = false;
}
// context === org.apache.catalina.core.StandardContext
configureContext(webXml); // 把解析处理的内容设置到 context 中 ,如:context.addFilterMap(filterMap);
}
//监听器的配置信息
private void configureContext(WebXml webxml) {
for (String listener : webxml.getListeners()) { // 应用监听器 <listener></listener>
context.addApplicationListener(listener);
}
}
}