tomcat及springboot實現Filter、Servlet、Listener
阿新 • • 發佈:2021-07-22
tomcat實現:
核心類org.apache.catalina.startup.ContextConfig
//支援註解 see:org.apache.catalina.deploy.WebXml protected void processClass(WebXml fragment, JavaClass clazz) { AnnotationEntry[] annotationsEntries = clazz.getAnnotationEntries(); if (annotationsEntries != null) { String className = clazz.getClassName(); for (AnnotationEntry ae : annotationsEntries) { String type = ae.getAnnotationType(); if ("Ljavax/servlet/annotation/WebServlet;".equals(type)) { processAnnotationWebServlet(className, ae, fragment); }else if ("Ljavax/servlet/annotation/WebFilter;".equals(type)) { processAnnotationWebFilter(className, ae, fragment); }else if ("Ljavax/servlet/annotation/WebListener;".equals(type)) { fragment.addListener(className); } else { // Unknown annotation - ignore } } } } //支援web.xml protected InputSource getContextWebXmlSource() { InputStream stream = null; InputSource source = null; URL url = null; String altDDName = null; // Open the application web.xml file, if it exists ServletContext servletContext = context.getServletContext(); try { if (servletContext != null) { altDDName = (String)servletContext.getAttribute(Globals.ALT_DD_ATTR); if (altDDName != null) { try { stream = new FileInputStream(altDDName); url = new File(altDDName).toURI().toURL(); } catch (FileNotFoundException e) { log.error(sm.getString("contextConfig.altDDNotFound", altDDName)); } catch (MalformedURLException e) { log.error(sm.getString("contextConfig.applicationUrl")); } } else { stream = servletContext.getResourceAsStream (Constants.ApplicationWebXml);//Constants.ApplicationWebXml = "/WEB-INF/web.xml" try { url = servletContext.getResource( Constants.ApplicationWebXml); } catch (MalformedURLException e) { log.error(sm.getString("contextConfig.applicationUrl")); } } } if (stream == null || url == null) { if (log.isDebugEnabled()) { log.debug(sm.getString("contextConfig.applicationMissing") + " " + context); } } else { source = new InputSource(url.toExternalForm()); source.setByteStream(stream); } } finally { if (source == null && stream != null) { try { stream.close(); } catch (IOException e) { // Ignore } } } return source; }
springboot中做了增強:
核心類:org.springframework.boot.web.servlet.ServletContextInitializerBeans org.springframework.boot.web.servlet.ServletListenerRegistrationBean均實現ServletContextInitializer介面,spring啟動tomcat時被呼叫
class TomcatStarter implements ServletContainerInitializer { private static final Log logger = LogFactory.getLog(TomcatStarter.class); private final ServletContextInitializer[] initializers; private volatile Exception startUpException; TomcatStarter(ServletContextInitializer[] initializers) { this.initializers = initializers; } @Override public void onStartup(Set<Class<?>> classes, ServletContext servletContext) throws ServletException { try { for (ServletContextInitializer initializer : this.initializers) { //因為ServletContextInitializerBeans和ServletListenerRegistrationBean均實現此類,故啟動時會被註冊到tomcat容器中 initializer.onStartup(servletContext); } } catch (Exception ex) { this.startUpException = ex; // Prevent Tomcat from logging and re-throwing when we know we can // deal with it in the main thread, but log for information here. if (logger.isErrorEnabled()) { logger.error("Error starting Tomcat context. Exception: " + ex.getClass().getName() + ". Message: " + ex.getMessage()); } } } public Exception getStartUpException() { return this.startUpException; } }