Tomcat8.x 中对ServletContainerInitializer接口的实现类的检测和自动调用

import java.util.Set;

import javax.servlet.ServletContainerInitializer;


// ************** ServletContainerInitializer接口 的使用 ************** 
		// 1、在jar包中创建META-INF/services/javax.servlet.ServletContainerInitializer文件
		// 2、在文件中写入实现的类路径,如:org.apache.jasper.servlet.JasperInitializer
		
		// ************** Tomcat中对ServletContainerInitializer接口的实现类的检测和自动调用 **************
		// 检测实现ServletContainerInitializer接口的类---------------------------1
		class org.apache.catalina.core.StandardContext{
			protected synchronized void startInternal() throws LifecycleException {
				 // 读取并解析“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);
                
                // 在org.apache.catalina.core.NamingContextListener事件处理器中,内部调用了createNamingContext()创建 envCtx
                // Notify our interested LifecycleListeners  触发事件监听器  org.apache.catalina.startup.ContextConfig
                fireLifecycleEvent(Lifecycle.CONFIGURE_START_EVENT, null); // 配置启动事件 "configure_start"----------------------
			}
			
			// 添加初始化器
			public void addServletContainerInitializer(
		            ServletContainerInitializer sci, Set<Class<?>> classes) {
		        initializers.put(sci, classes);
		    }
		}

		class org.apache.catalina.startup.ContextConfig{
			public void lifecycleEvent(LifecycleEvent event) {
				context = (Context) event.getLifecycle(); // 取得触发者 org.apache.catalina.core.StandardContext
				configureStart();
			}
			
			 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() {
				 	// org.apache.jasper.servlet.JasperInitializer  jasper.jar
		            // org.apache.tomcat.websocket.server.WsSci    tomcat-websocket.jar
		        	
		        	// 解析类路径中"META-INF/services/javax.servlet.ServletContainerInitializer"文件内容
		            // 创建文件中声明的类型对象,并把创建对象转成ServletContainerInitializer类型的引用
//		        	initializerClassMap{
//		            	'MyServletContainerInitializer1_Obj'=>[],
//		            	'MyServletContainerInitializer2_Obj'=>[],
//		            }
//		        	typeInitializerMap{
//		            	'MyAnnotation1.class'=>[MyServletContainerInitializer1_Obj ],
//		            	'MyAnnotation2.class'=>[MyServletContainerInitializer2_Obj ]
//		            }
				 	
		            processServletContainerInitializers(); // 查看实现ServletContainerInitializer的初始化器
		            
		            
		            if (ok) {
		            	// org.apache.jasper.servlet.JasperInitializer  jasper.jar
		                // org.apache.tomcat.websocket.server.WsSci    tomcat-websocket.jar
		            	
		            	// 解析类路径中"META-INF/services/javax.servlet.ServletContainerInitializer"文件内容
		                // 创建文件中声明的类型对象,并把创建对象转成ServletContainerInitializer类型的引用
//		            	initializerClassMap{
//		                	'MyServletContainerInitializer1_Obj'=>[],
//		                	'MyServletContainerInitializer2_Obj'=>[],
//		                }
//		            	typeInitializerMap{
//		                	'MyAnnotation1.class'=>[MyServletContainerInitializer1_Obj ],
//		                	'MyAnnotation2.class'=>[MyServletContainerInitializer2_Obj ]
//		                }
		                for (Map.Entry<ServletContainerInitializer,Set<Class<?>>> entry : initializerClassMap.entrySet()) {
		                    if (entry.getValue().isEmpty()) { // 添加Servlet容器初始化器到StandardContext
		                    	// 添加初始化器
		                    	// context === org.apache.catalina.core.StandardContext
		                    	// StandardContext.initializers.put(entry.getKey(), null);
		                        context.addServletContainerInitializer(
		                                entry.getKey(), null); 
		                    } else {
		                        context.addServletContainerInitializer(
		                                entry.getKey(), entry.getValue());
		                    }
		                }
		            }
		            
		            protected void processServletContainerInitializers() {
		            	// 容器初始化器
		                WebappServiceLoader<ServletContainerInitializer> loader = new WebappServiceLoader<>(context);
		                // org.apache.jasper.servlet.JasperInitializer  jasper.jar
		                // org.apache.tomcat.websocket.server.WsSci    tomcat-websocket.jar
		                // 解析类路径中"META-INF/services/javax.servlet.ServletContainerInitializer"文件内容
		                // 创建文件中声明的类型对象,并把创建对象转成ServletContainerInitializer类型的引用
		                detectedScis = loader.load(ServletContainerInitializer.class); // 检测到的 ServletContainerInitializer
		                for (ServletContainerInitializer sci : detectedScis) {
		                    initializerClassMap.put(sci, new HashSet<Class<?>>()); // 要调用的初始化器
		                }
		            }
			 }
			 
			 // 调用实现ServletContainerInitializer接口的类的方法,进行初始化---------------------------2
			 class org.apache.catalina.core.StandardContext{
					protected synchronized void startInternal() throws LifecycleException {
						// fireLifecycleEvent(Lifecycle.CONFIGURE_START_EVENT, null);
						// ....
						
						// org.apache.jasper.servlet.JasperInitializer  jasper.jar
		                // org.apache.tomcat.websocket.server.WsSci    tomcat-websocket.jar
						
						// Call ServletContainerInitializers
			            for (Map.Entry<ServletContainerInitializer, Set<Class<?>>> entry :
			                initializers.entrySet()) { // 调用容器初始化器 ,
			            	// 如:org.apache.jasper.servlet.JasperInitializer.onStartup(); 
			                try {
			                	// 执行初始化器
			                    entry.getKey().onStartup(entry.getValue(),getServletContext());
			                } catch (ServletException e) {
			                    log.error(sm.getString("standardContext.sciFail"), e);
			                    ok = false;
			                    break;
			                }
			            }
					}
				}

		}







  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值