• tomcat及springboot实现Filter、Servlet、Listener


    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.ServletRegistrationBean 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) {
                                    //因为ServletListenerRegistrationBean FilterRegistrationBean 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;
    	}
    
    }
    

    https://mp.weixin.qq.com/s/Z3ZemxPHBDAUWE-YEHyyDg

  • 相关阅读:
    利用同步辅助类CountDownLatch计算多线程的运行时间
    i++的原子性问题
    Volatile关键字以及线程的内存可见性问题
    创建线程的第三种方式以及简单使用
    java8新特性-lambda表达式和stream API的简单使用
    springboot整合activemq
    springboot整合redis单机及集群
    JAVA-基础(一)
    CentOS-文件操作
    理解AngularJS的作用域Scope
  • 原文地址:https://www.cnblogs.com/zhangww/p/14991721.html
Copyright © 2020-2023  润新知