ServletContextListener和ServletContainerInitializer实现类的处理时机
今天我们一起来探索一下,ServletContextListener和ServletContainerInitializer实现类的处理时机
选用的tomcat版本 8.5.50
ServletContainerInitializer
1.执行链路见下图:
2.关键代码在org.apache.catalina.core.StandardContext#startInternal里边
for (Map.Entry<ServletContainerInitializer, Set<Class<?>>> entry :
initializers.entrySet()) {
try {
entry.getKey().onStartup(entry.getValue(),getServletContext());
} catch (ServletException e) {
log.error(sm.getString("standardContext.sciFail"), e);
ok = false;
break;
}
}
spring在servlet3.0后就使用了ServletContainerInitializer这种机制,来初始化spring上文
ServletContextListener
1.执行链路见下图:
2.关键代码在org.apache.catalina.core.StandardContext#listenerStart里边
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;
}
}
在servlet3.0之前都是采用ServletContextListener这种机制来初始化spring上下文。