一些基本概念
1、ServletContext:
作用:表示一个web应用的上下文;可以想象成一个Web应用程序的共享数据区域,该区域保存该Web应用程序的共享数据;
生命周期:每个Web应用程序都对应一个ServletContext,保存在Context中,在Context初始化时创建,Context撤销时销毁;
2、servlet-mapping:
作用:按url将请求匹配到servlet;
匹配过程:1) url按最长context path匹配当前Host下的Context;
2) 余下的将用于匹配该Context下的Servlet;
匹配规则,顺序如下:
1) 精确匹配:如/user/login;必须以/开头,不能以/*结尾;
2) 通配符匹配:如/customers/*,以最长串优先依次匹配;
3) 扩展名匹配:如/user/register.jsp;任何以*开头,以jsp结尾的mapping都会匹配;
4) 默认匹配:上述3种匹配失败后,将匹配到该mapping上;
3、Filter:
作用:Filter使用户可以改变一个request和修改一个response,它不是一个servlet,也不能产生response,它能够在一个request到达servlet之前预处理request,也可以在response离开servlet时处理response。
类图:如下
其中:
1) FilterDef用于保存从web.xml解析出来的filter定义,包含filterName, filterClass, init-param等;
2) FilterMap用于保存从web.xml解析出来的filter-mapping配置;
3) 当初始化完所有的FilterDef以及FilterMap后,容器会初始化ApplicationFilterConfig,用于Filter内部访问Tomcat容器,如Filter的init-param, ServletContext等;
4) 解析出来的FilterDef、FilterMap以及ApplicationFilterConfig均保存在StandardContext中;
4、Listener:
作用:通过在web.xml中配置<listener>元素,可以在适当的时候收到Tomcat容器的事件通知,从而可以做出相应的响应;
类型:
1) 事件类型:当某事件发生时触发;
a) ServletContextAttributeListener:当ServletContext的属性发生变化(新增、修改、删除)时触发;
b) ServletRequestAttributeListener:当request的属性发生变化(新增、修改、删除)时响应;
c) ServletRequestListener:当请求在经Filter链处理前后时响应;
d) HttpSessionAttributeListener:当session中的属性发生变化(新增、修改、删除)时响应;
2) 生命周期类型:在生命周期中的某个点触发;
a) ServletContextListener:在ServletContext初始化完成和销毁时触发;
b) HttpSessionListener:在session创建和销毁时触发;
重要的数据结构
1、Mapper:
保存Tomcat容器中所有Host, Context, Wrapper及servlet-mapping的映射关系;
2、MappingData:
当前请求经过Mapper后,即决定将该请求交给哪个Host, 哪个Context, 哪个Wrapper来处理;这些数据组成MappingData;
创建ServletContext
1、ServletContext类图
这里采用了门面模式,ApplicationContext仅供tomcat内部使用,在Servlet中取得的servletContext实际上是ApplicationContextFacade的实例,防止外部修改tomcat容器中重要的数据结构;2、实例化ServletContext实例化ServletContext是通过StandardContext.getServletContext()方法来完成的:
public ServletContext getServletContext() {
if (context == null) {
context = new ApplicationContext(getBasePath(), this);
if (altDDName != null)
context.setAttribute(Globals.ALT_DD_ATTR,altDDName);
}
return (context.getFacade());
}
解析部署描述符web.xml1、初始化Wrapper当StandardContext初始化时,会解析web.xml文件(参考WebRuleSet);当解析到web-app/servlet标签时会调用StandardContext.createWrapper()方法,从而构造Wrapper组件,并将其作为子节点添加到当前Context下;初始化Wrapper后,会设置与该servlet相关的配置,如servlet-name, servlet-class, init-param, jsp-file, load-on-startup等;这些配置值都是刚才构建出来的Wrapper组件的属性;2、初始化servlet-mapping由于servlet-mapping是针对Context的,处理servlet-mapping的工作由Context来完成,主要工作如下:1) 根据servert-name找到该Context的子节点Wrapper,然后将该mapping添加到Wrapper中;2) 将该Wrapper添加到当前Context的Mapper中,供ServletContext使用;3、初始化filter及filter-mapping1) 解析filter:调用StandardContext.addFilterDef(FilterDef filterDef),如下:
public void addFilterDef(FilterDef filterDef) {
synchronized (filterDefs) {
filterDefs.put(filterDef.getFilterName(), filterDef);
}
fireContainerEvent("addFilterDef", filterDef);
}
即:将filterDef以filterName为key保存在Map中;2) 解析filter-mapping:调用StandardContext.addFilterMap(FilterMap filterMap),如下:
public void addFilterMap(FilterMap filterMap) {
// 先会做一些校验
synchronized (filterMaps) {
FilterMap results[] =new FilterMap[filterMaps.length + 1];
System.arraycopy(filterMaps, 0, results, 0, filterMaps.length);
results[filterMaps.length] = filterMap;
filterMaps = results;
}
fireContainerEvent("addFilterMap", filterMap);
}
3) 初始化ApplicationFilterConfig:当StandardContext启动时,会通过filterStart()方法来初始化ApplicationFilterConfig:将1)中保存的每个filterDef和当前StandardContext包装成一个ApplicationFilterConfig,供后面的创建filter链时使用;4、初始化listener当解析到web.xml中的<listener>元素时,会调用Standard.addApplicationListener(String listener)将listener的class信息保存起来,然后在StandardContext启动时,通过listenerStart()方法来初始化listener:实例化先前保存起来的listener,并按事件/生命周期分类保存其实例;此时StandardContext初始化也快完成了,因此会触发ServletContextListener.contextInitialized()方法;Servlet的loadOnStartup在配置Servlet时,可以指定其loadOnStartup属性,该属性值决定了Servlet在容器启动后是否加载及加载顺序,默认为-1,表示不加载;StandardContext在加载完所有Servlet配置后,会检查当前Context下的所有Wrapper的loadOnStartup属性值,当值大于0时,通过TreeMap按loadOnStartup从小到大排序后,分别调用每个Wrapper.load()方法来完成Servlet的初始化:1) 根据servletClass是否是Tomcat内部servlet,决定是用webappClassloader还是用serverClassloader来装载servletClass;2) 实例化servletClass;3) 如果servlet是单线程(即一个servlet实例同时只能处理一个请求),则初始化一个servlet pool,用于存放空闲的servlet实例;后面在处理请求时分配servlet则会用到该servlet pool;Mapper相关1、先看看Mapper相关的类图
请不要把上图中的Host, Context, Wrapper和Tomcat中的Host组件、Context组件、Wrapper组件相混淆了,它们仅仅代表这三个组件的映射关系,真正所对应的组件实例引用存放在MapperElement抽象类中的object属性上;2、初始化Mapper结构我们再来回顾一下Tomcat容器的初始化过程:1) 解析server.xml(由Catalina类来完成),同时调用StandardServer.start()方法来初始化Server组件;2) Server组件初始化时,调用StandardService.start()方法来初始化Service组件;3) 在StandardService.start()中,先完成所有内嵌组件的初始化(Engine, Host, Context, Wrapper等),然后调用Connect.start()方法来初始化Connector组件;4) 由于在Connector初始化时,所有的内嵌组件都已初始化完毕,此时便可以完成Mapper的构造了;初始化Mapper主要是由MapperListener来完成(在Connector.start()中调用MapperListener.init()方法):1) 注册Engine:找到defaultHost,并设置Mapper的defaultHostName属性;2) 注册所有的Host:针对每个Host组件,都构造一个Mapper$Host实例,name属性为该Host组件的name,object属性即该Host组件;另外,针对Host组件的别名,也会产生新的Mapper$Host实例,不过其object和Mapper$contextList的引用相同;3) 注册所有的Context:针对每个Context组件,根据其hostName,将其加到对应Mapper$Host实例的Mapper$contextList中去;4) 注册所有的Wrapper:和注册Context类似,将每个Wrapper组件根据其servlet-mapping保存到Mapper$Context的相应属性上;3、MappingData的构造当请求到达后,在交给Engine处理前,会构造MappingData(见CoyoteAdapter.postParseRequest()方法):1) 根据请求的host属性,从Mapper中找到相应的Host组件及Mapper$Context数组;此时如果没有指定host属性的Host组件,则取defaultHostName所对应的Host组件;2) 根据请求的uri,找到Context组件;3) 根据请求的uri,按servlet-mapping规则,依次查找,直接找到对应的Wrapper组件;此时如果找不到,则依次查找welcomeFile所对应Wrapper组件;4) 如果最后还是没有找到,则返回defaultWrapper组件;5) 将匹配到的Host, Context, Wrapper保存在request中;Wrapper组件对请求的处理当MappingData构造完成后,CoyoteAdapter便将请求交给Engine、Host、Context、Wrapper组件进行处理;在Context组件中,StandardContextValve直接从request中取出Wrapper,然后交给它处理;下面看看Wrapper组件是如何处理的?1、StandardWrapperValveWrapper组件对请求的处理,是通过StandardWrapperValve来完成的:1) 从Wrapper中分配一个servlet实例;2) 根据当前servlet和requestPath将匹配到的filter加到filter链中;3) 调用filter chain处理请求和响应;当所有filter执行完,最后才执行servlet.service()方法;
分享到:
相关推荐
@ vue / web-component-wrapper 包装并将Vue组件注册为自定义元素。兼容性。 不支持IE11及以下版本。 如果定位本机支持ES2015但不支持本机Web组件的浏览器: 您还将需要 。 有关和支持,请访问caniuse.com。 使用...
java wrapper 分布式应用组件、可以把java程序以服务的形式分布于不同的服务器
对于tomcat的启动流程分析,从主流程Bootstrap -> Catalina -> Server -> service -> engine,connector;和分流程1.engine->host->context->wrapper ;2.connector -> ProtocolHandler->Endpoint;之中的方法调用进行...
通过学习《深入剖析Tomcat》,你将可以自行开发Tomcat组件,或者扩展已有的组件。 Tomcat是目前比较流行的Web服务器之一。作为一个开源和小型的轻量级应用服务器,Tomcat 易于使用,便于部署,但Tomcat本身是一个...
QueryWrapper 常用用法
懒惰地ReactIMG React Lazily IMG是一个React Wrapper组件,用于延迟加载图像。 目标是使用方便且已知的标准HTML标记,并只是延迟加载它们。特征图片标签和IMG srcset支持Webp检测占位符HTML && CSS图像支持下载图像...
redux-auth-wrapper 使您的身份验证和授权与组件脱钩! npm install --save redux-auth-wrapper redux-auth-wrapper是一个实用程序库,用于在react + redux应用程序中处理身份验证和授权。 阅读位于的文档版本3 版本...
去CSDN下载所谓破解出现以下错误:wrapper | Licensed to (null) for (null) wrapper | wrapper | Launching a JVM... jvm 1 | WrapperManager: Initializing... jvm 1 | WrapperJNI Error: Not licensed to use ...
Tomcat监控工具Probe 1.Porbe介绍 psi-probe用于对Tomcat进行监控,比tomcat的manager强大很多。 2.下载 probe-2.3.3.zip 或者 probe.war 3.将下载好的war包,或者zip文件,放在tomcat的webapp目录下 4...
用wrapper包装的resin4 不需要.net组件即可启动
MyBatisPlus条件构造器 -Wrapper详解(为知笔记版,可用网页打开),详解wrapper条件构造器的各种使用方法及其扩展类的使用方法。
RDP Wrapper对应的配置文件,支持10.0.1904.1503
主要介绍了tomcat报错:Wrapper cannot find servlet class ...问题解决的相关资料,需要的朋友可以参考下
现场演示产品特点Wc-menu-wrapper是一个不使用影子DOM的独立香草JS Web组件。 组件功能包括: 内容不可知:菜单项应能够包含任何HTML 可嵌套的:允许创建通用的菜单子菜单结构菜单“放下”方向:向下或向右初始菜单...
windows程序设计(珍藏版)_wrapper_wrapperwindows程序设计(珍藏版)_wrapper_wrapperwindows程序设计(珍藏版)_wrapper_wrapper
在开发中老是面对黑乎乎的tomcat窗口总是很烦躁,还担心被关掉,利用Java Service Wrapper将tomcat写入系统服务是件很不错的选择,100%原创
wrapper java window系统服务
RDP Wrapper10.0.19041.84,win10多用户
C:\Users\Administrator\.m2\wrapper 解压到这里 方便idea调用
wrapper.h头文件都在里面了,我的操作系统实验作业源码是需要这里的头文件才可以运行,当然这个头文件只是相当于万能头文件,你也可以按自己的经验添加部分头文件即可运行我的源码。(最后拜托审核员大大不要修改我...