分类: WEB服务器2012-08-30 22:16 1547人阅读 评论(0) 收藏 举报

Wrapper 代表一个 Servlet,它负责管理一个 Servlet,包括的 Servlet 的装载、初始化、执行以及资源回收。它的父容器一般是Context,Wrapper 是最底层的容器,它没有子容器了,所以调用它的 addChild 将会抛illegalargumentexception。Wrapper 的实现类是 StandardWrapper,StandardWrapper 还实现了拥有一个 Servlet 初始化信息的 ServletConfig,由此看出 StandardWrapper 将直接和 Servlet 的各种信息打交道。

在StandardContext启动时,读取web.xml配置文件,配置Context之后,紧接着启动Context的一些附属组件,除此以外还加载了那些标记为"load on start"的那些wrapper

  1. // Load and initialize all "load on startup" servlets
  2. if (ok) {
  3. loadOnStartup(findChildren());
  4. }
  1. public void loadOnStartup(Container children[]) {
  2. // Collect "load on startup" servlets that need to be initialized
  3. TreeMap<Integer, ArrayList<Wrapper>> map =
  4. new TreeMap<Integer, ArrayList<Wrapper>>();
  5. for (int i = 0; i < children.length; i++) {
  6. Wrapper wrapper = (Wrapper) children[i];
  7. int loadOnStartup = wrapper.getLoadOnStartup();
  8. if (loadOnStartup < 0)
  9. continue;
  10. Integer key = Integer.valueOf(loadOnStartup);
  11. ArrayList<Wrapper> list = map.get(key);
  12. if (list == null) {
  13. list = new ArrayList<Wrapper>();
  14. map.put(key, list);
  15. }
  16. list.add(wrapper);
  17. }
  18. // Load the collected "load on startup" servlets
  19. for (ArrayList<Wrapper> list : map.values()) {
  20. for (Wrapper wrapper : list) {
  21. try {
  22. wrapper.load();
  23. } catch (ServletException e) {
  24. getLogger().error(sm.getString("standardWrapper.loadException",
  25. getName()), StandardWrapper.getRootCause(e));
  26. // NOTE: load errors (including a servlet that throws
  27. // UnavailableException from tht init() method) are NOT
  28. // fatal to application startup
  29. }
  30. }
  31. }
  32. }

这个方法做了两件事:

1、遍历这些wrapper,将其放入一个map中。key为启动顺序,value是同一启动顺序的servlet list,为了保护数字小的先启动,这里用了treemap这种数据结构来存储;

2、遍历这个map,依次加载对应list中的各个wrapper。由于采用的是arrayList,所以相同"load on start"值靠前的先加载

下面来看看StandardWrapper的load方法,直接调用了loadServlet方法来初始化

  1. public synchronized void load() throws ServletException {
  2. instance = loadServlet();
  3. if (!instanceInitialized) {
  4. initServlet(instance);
  5. }
  6. if (isJspServlet) {
  7. StringBuilder oname =
  8. new StringBuilder(MBeanUtils.getDomain(getParent()));
  9. oname.append(":type=JspMonitor,name=");
  10. oname.append(getName());
  11. oname.append(getWebModuleKeyProperties());
  12. try {
  13. jspMonitorON = new ObjectName(oname.toString());
  14. Registry.getRegistry(null, null)
  15. .registerComponent(instance, jspMonitorON, null);
  16. } catch( Exception ex ) {
  17. log.info("Error registering JSP monitoring with jmx " +
  18. instance);
  19. }
  20. }
  21. }
  1. private synchronized void initServlet(Servlet servlet)throws ServletException {
  2. if (instanceInitialized && !singleThreadModel) return;
  3. // Call the initialization method of this servlet
  4. try {
  5. instanceSupport.fireInstanceEvent(InstanceEvent.BEFORE_INIT_EVENT, servlet);
  6. if (Globals.IS_SECURITY_ENABLED) {
  7. Object[] args = new Object[] { (facade) };
  8. SecurityUtil.doAsPrivilege("init", servlet, classType, args);
  9. args = null;
  10. } else {
  11. servlet.init(facade);
  12. }
  13. instanceInitialized = true;
  14. instanceSupport.fireInstanceEvent(InstanceEvent.AFTER_INIT_EVENT, servlet);
  15. } catch (UnavailableException f) {
  16. //handle exception
  17. }
  18. }

实际上是调用了servlet的init方法,这已经是servlet的代码了,这里不再分析。

前面提到的servlet的加载只是被标识为“load on start”的那些servlet,那么其他servlet是在什么时候被加载的呢?选中StandardWrapper的initServlet方法,在eclipse中查看其调用层次如下:

会发现有个allocate方法间接调用了它,这里给出请求进入wrapper之后的方法调用时序图:

可以看出在请求进入wrapper之后,通过allocate方法从实例池栈中弹出一个servlet实例来处理这个请求,servlet实例被封装成filterChain对象,紧接着通过一系列的过滤器过滤到达servlet.service()方法,这是singleThreadModel模式的做法。在非singleThreadModel模式的情况下首次加载并初始始化servlet赋给instance字段,下次直接从这个字段中获取servlet实例,因此在非singleThreadModel模式下每次返回的是同一个servlet实例。有关singleThreadModel的具体介绍参考:http://tomcat.apache.org/tomcat-5.5-doc/servletapi/javax/servlet/SingleThreadModel.html

Tomcat学习之Wrapper的更多相关文章

  1. Tomcat 学习进阶历程之Tomcat架构与核心类分析

    前面的http及socket两部分内容,主要是为了后面看Tomcat源代码而学习的一些网络基础.从这章開始.就開始实际深入到Tomcat的'内在'去看一看. 在分析Tomcat的源代码之前,准备先看一 ...

  2. Tomcat学习—Tomcat的简介和目录以及配置文件介绍(Windows环境)

    tomcat学习(8) 版权声明:本文为博主原创文章,未经博主允许不得转载. 今天学习TOMCAT,主要学习的是Tomcat的目录结构,配置文件! 1:Tomcat简介 Tomcat 服务器是一个免费 ...

  3. Tomcat学习之ClassLoader

    Tomcat学习之ClassLoader 2012-09-04 22:19 8993人阅读 评论(4) 收藏 举报  分类: WEB服务器(13)  版权声明:本文为博主原创文章,未经博主允许不得转载 ...

  4. tomcat学习步骤,附带打破双亲委派模型企业应用实战

    1. tomcat入门 入门模块仅做学习大纲梳理,忽略了具体操作指引. Tomcat的三种部署模式: 简单架构模型 连接器的非阻塞模式(NIO) 通道(Channel).缓冲区(Buffer).选择器 ...

  5. Tomcat学习记录

    阅读摘录如下: 本质 Tomcat最本质就是个能运行JSP/Servlet的Web服务器 , 因此最典型的应用就是用户通过浏览器访问服务器,Tomcat接收到请求后转发给Servlet,由Servle ...

  6. Tomcat 学习笔记二

    学习一 java.bean.PropertyChangeListener用来监听bean类的属性值改变.当改变时同时执行对应事件.而且是线程安全的.tomcat用此reload的Boolean值改变是 ...

  7. Tomcat ----> 学习笔记

    源码之几个常见类和接口的关系 在学习Servlet的时候经常见到以下几个合成单词和非合成单词:Servlet.GenericServlet.HttpServlet.它们之间有联系的.接下来我把它们的联 ...

  8. Tomcat学习总结(7)——Tomcat与Jetty比较

    Jetty 基本架构 Jetty目前的是一个比较被看好的 Servlet 引擎,它的架构比较简单,也是一个可扩展性和非常灵活的应用服务器. 它有一个基本数据模型,这个数据模型就是 Handler(处理 ...

  9. Tomcat学习总结(3)——Tomcat优化详细教程

    Tomcat是我们经常使用的 servlet容器之一,甚至很多线上产品都使用 Tomcat充当服务器.而且优化后的Tomcat性能提升显著,本文从以下几方面进行分析优化. 一.内存优化 默认情况下To ...

随机推荐

  1. js原型对象中属性被覆盖(1)

    /**   *@author 程无衣   *@description 关于在原型对象中属性被覆盖   */       function Person(){}       Person.prototy ...

  2. Grunt自动化工具相关

    Grunt 项目中安装grunt模块npm install grunt --save,删除模块 npm uninstall grunt ,缺失某个插件:npm install grunt-contri ...

  3. W5100硬件设计和调试要点

    文章来源:成都浩然 与MCU的接口 W5100与MCU接口採用并行总线方式(假设要使用SPI接口,建议採用W5200),因此W5100与MCU的接口设计相对简单.以AT89C52为例,例如以下图所看到 ...

  4. Selenium chrome配置不加载图片

    from selenium import webdriver chrome_options = webdriver.ChromeOptions() prefs = {"profile.man ...

  5. Java基础—String总结

    特点 String不属于8种基本数据类型,String是一个对象. 因为对象的默认值是null,所以String的默认值也是null:但它又是一种特殊的对象,有其它对象没有的一些特性. String实 ...

  6. ZRGGBS00 GGB1替代问题

    ZRGGBS00ZRGGBS00ZRGGBS00 和Validation不同的是,Validation只做检测,一般不做相应数据的修改,Substitution弥补了这反面的缺陷,它和user exi ...

  7. 20170405-STO库存转储单

    1.工厂间转储: (1)MB1B 移动类型 301 工厂到工厂(一步)转账,->简单明了一步转储过账后会产生 GR,MITA增加了,MIZH减少了,MB03, **会产生 GR,如果俩工厂 标准 ...

  8. Python常见序列详解

    一.Python中序列的分类 常见序列类型包括字符串(普通字符串和unicode字符串),列表和元组.所谓序列,即成员有序排列,可通过下标访问. 二.Python序列通用操作 下面我们将分别以字符串. ...

  9. Android 工具类 SharedPreferences 封装

    SharedPreferences 是 Android 数据存储方式中的一种,特别适合用来存储少量的.格式简单的数据,比如应用程序的各种配置信息,如是否打开音效,是否开启震动等等. SharedPre ...

  10. pyhton3 random模块

    random是内建(built-in)函数,作用是产生随机数 导入模块: import random 接着就可以调用random模块下的函数了使用 dir(random)可以查看random模块下有哪 ...