当前位置: 首页 > 编程日记 > 正文

how tomcat works 总结 二


第五章 servlet容器

第 5 章讨论 container 模块。container 指的是 org.apache.catalina.Container 接口,有4 种类型的 container:engine, host, context 和 wrapper。这章提供了两个工作于 context 和wrapper 的程序。
容器共分四类,类图例如以下:

一个wrapper就是一个servlet;
一个context包括若干个wrapper;
本章分了两个部分,第一部分是wrapper,第二部分是context。


第一部分 wrapper

这一章说白了就是具体分解了第四章SimpleContainer中的invoke方法!
public class SimpleWrapper implements Wrapper, Pipeline {// the servlet instanceprivate Servlet instance = null;private String servletClass;private Loader loader;private String name;private SimplePipeline pipeline = new SimplePipeline(this);protected Container parent = null;public SimpleWrapper() {pipeline.setBasic(new SimpleWrapperValve());}public synchronized void addValve(Valve valve) {pipeline.addValve(valve);}...
}
既然说到了容器,就得说说管道(每一级容器中,都有一个管道);把我们的命令比作流水,在(流水)命令接触终于的servlet之前,会有一个长长的管道(SimplePipeline),管道里有一个一个的阀(Valve),每个阀都会做一个任务!就这么简单,在管道里面有一个基础阀(SimpleWrapperValve),而这个基础阀就用来生成servlet,调用其service方法。


wrapper程序的类图例如以下:

流程例如以下
先是调用wrapper的invoke;

SimpleWrapper.javapublic void invoke(Request request, Response response)throws IOException, ServletException {pipeline.invoke(request, response);}
再调用管道的invoke;
SimplePipeline.javapublic void invoke(Request request, Response response)throws IOException, ServletException {// Invoke the first Valve in this pipeline for this request(new SimplePipelineValveContext()).invokeNext(request, response);}SimplePipelineValveContext为SimplePipeline的内部类,作用就是循环全部的阀,最后调用基础阀(就是以下代码中的basic)SimplePipelineValveContext.javapublic void invokeNext(Request request, Response response)throws IOException, ServletException {int subscript = stage;stage = stage + 1;// Invoke the requested Valve for the current request threadif (subscript < valves.length) {valves[subscript].invoke(request, response, this);}else if ((subscript == valves.length) && (basic != null)) {basic.invoke(request, response, this);}else {throw new ServletException("No valve");}}


 这部分的基础阀就是SimpleWrapperValve(在构造simplewrapper时就指定了),基础阀会调用反射生成servlet类......

第二部分 context

类图例如以下:



绝大部分的web程序不可能仅仅有一个servlet,多个servlet就会构成一个context。
 换句话说,一个context里面有多个wrapper。
 那么如今就有问题了,多个wrapper总得有个记录,请求1应该让哪个wrapper来处理,请求2又该让哪个wrapper处理等等。


 因此就有了mapper接口,我们这里用的是事实上现类,simplecontextmapper。其map方法就能返回对应的wrapper。

 public Container map(Request request, boolean update) {String requestURI = ((HttpRequest) request).getDecodedRequestURI();String relativeURI = requestURI.substring(contextPath.length());Wrapper wrapper = null;String name = context.findServletMapping(relativeURI);if (name != null)wrapper = (Wrapper) context.findChild(name);return (wrapper);}
找到wrapper就和上一部分的过程一样了。

第六章 生命周期

第 6 章解释了 Lifecycle 接口。这个接口定义了一个 Catalina 组件的生命周期。并提供了一个优雅的方式。用来把在该组件发生的事件通知其它组件。另外。Lifecycle 接口提供了一个优雅的机制,用于在 Catalina 通过单一的 start/stop 来启动和停止组件。


本章类图:

tomcat是组件化的软件。全部的组件都实现了Lifecycle接口,里面有start与stop方法;我们如今想要的效果就是,我仅仅用启动一个组件系统就能帮我把全部的都启动,关闭也是一样。

看上去非常复杂,事实上非常easy

public synchronized void start() throws LifecycleException {if (started)throw new LifecycleException("SimpleContext has already started");// Notify our interested LifecycleListenerslifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null);started = true;try {// Start our subordinate components, if anyif ((loader != null) && (loader instanceof Lifecycle))((Lifecycle) loader).start();// Start our child containers, if anyContainer children[] = findChildren();for (int i = 0; i < children.length; i++) {if (children[i] instanceof Lifecycle)((Lifecycle) children[i]).start();}// Start the Valves in our pipeline (including the basic),// if anyif (pipeline instanceof Lifecycle)((Lifecycle) pipeline).start();// Notify our interested LifecycleListenerslifecycle.fireLifecycleEvent(START_EVENT, null);}catch (Exception e) {e.printStackTrace();}
SimpleContext里面的各个组件依次启动就ok;
事实上这一章假设仅仅是说生命周期的话到这就结束了,但是假设说到观察者模式,那话就多了。
所谓观察者模式,说的简单点就是,我有了一个动作,就要通知一些关心我的人。就这么简单。


Bootstrap.javaLifecycleListener listener = new SimpleContextLifecycleListener();((Lifecycle) context).addLifecycleListener(listener);simplecontext.java
protected LifecycleSupport lifecycle = new LifecycleSupport(this);public void addLifecycleListener(LifecycleListener listener) {lifecycle.addLifecycleListener(listener);}
执行时,以下的代码就是告诉全部关心SimpleContext的监听者:SimpleContext类做了BEFORE_START_EVENT这个动作!
 lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null);
LifecycleSupport.javapublic void fireLifecycleEvent(String type, Object data) {LifecycleEvent event = new LifecycleEvent(lifecycle, type, data);LifecycleListener interested[] = null;synchronized (listeners) {interested = (LifecycleListener[]) listeners.clone();}for (int i = 0; i < interested.length; i++)      //循环通知全部关注者interested[i].lifecycleEvent(event);}// 一个详细的关注者
public class SimpleContextLifecycleListener implements LifecycleListener {@SuppressWarnings("unused")
public void lifecycleEvent(LifecycleEvent event) {Lifecycle lifecycle = event.getLifecycle();System.out.println("SimpleContextLifecycleListener's event " +event.getType().toString());if (Lifecycle.START_EVENT.equals(event.getType())) {System.out.println("Starting context.");}else if (Lifecycle.STOP_EVENT.equals(event.getType())) {System.out.println("Stopping context.");}}
}


相关文章:

策略模式(Strategy)

这是来数理系LSGO软件技术团队学习Coding&#xff0c;第二个要学习的设计模式。该模式在解决同一个问题时可以使用不同的算法。以满足“开闭原则”&#xff0c;把各种算法与实际业务逻辑解耦合&#xff0c;以便写出良好的代码。

[scrum]2011/9/22-----第二天

scrum 总结&#xff1a; Team member Yesterday’s Work Today’s Work Issue R X Task196:Completed xml 文件的解析&#xff0c;并且通过了两个测试用例 Task198:Completed 添加全局变量&#xff1a;当前会议和remind list Task201&#xff1a;Active 基本完成了select …

千千静听4.6.7版发布了

现在这个版本算是很不错的了&#xff0c;提供了相当完善的播放功能 下载&#xff1a; http://ttplayer.com/ttpsetup.exe 转载于:https://www.cnblogs.com/it201108/archive/2006/04/29/2148385.html

Strategy_Requirement1

以下代码是“策略模式”的第一个例子&#xff1a;

代码解说Android Scroller、VelocityTracker

在编写自己定义滑动控件时经常会用到Android触摸机制和Scroller及VelocityTracker。Android Touch系统简单介绍&#xff08;二&#xff09;:实例具体解释onInterceptTouchEvent与onTouchEvent的调用过程对Android触摸机制须要用到的函数进行了具体的解释。本文主要介绍两个重要…

写给云栖社区在做网站的朋友一点干货

我本人也是从事网站建设及APP开发业务的&#xff0c;工作多年下来&#xff0c;从以前的几百元企业网站&#xff0c;到商城网站&#xff0c;以及一些应用类型的APP开发&#xff0c;亲眼目睹了很多企业&#xff0c;以及很多项目&#xff0c;在应用的过程中&#xff0c;过了1-2年&…

Strategy_Requirement2

以下代码是“策略模式”的第二个例子&#xff1a;

如何启用SQL Server 2008的FILESTREAM特性

如何启用SQL Server 2008的FILESTREAM特性 今天安装SQL Server 2008的时候没有注意&#xff0c;忘记了启用FILESTREAM特性&#xff0c;因为默认情况下FILESTREAM是禁用的。安装完成后&#xff0c;再导入一个.bak的备份数据库时提示FILESTREAM feature is disabled&#xff0c;到…

如何在搜索结果出来之前,让页面显示“等待中。。。”

在当前页面点击搜索按纽后&#xff0c;当前页的button onclick事件会生成一个sql语句&#xff0c;然后转到查询结果页面&#xff0c;由于查询可能很费时间&#xff0c;客户要求在这两个页面中加入一个提示用户正在查询&#xff0c;请等待的页&#xff0c;具体的查询是在查询结果…

Strategy_Level1

以下代码是“策略模式”的第三个例子&#xff1a;

波士顿房价预测学习项目笔记

机器学习入门项目 作为机器学习的入门项目&#xff0c;了解到这个一个监督学习类型的回归问题模型。项目中需要根据已有的数据&#xff0c;构建一个合理的模型对未来的房价可以做出预测。 Udacity机器学习课程针对初学者做了精心地设计&#xff0c;这里来看项目是如何组织的&am…

LINQ之路19:LINQ to XML之X-DOM更新、和Value属性交互

本篇包含两部分内容&#xff1a;X-DOM更新一节中我们会详细讨论LINQ to XML的更新方式&#xff0c;包括Value的更新、子节点和属性的更新、通过Parent节点实现更新&#xff1b; 和Value属性交互一节会详细讨论XElement和XAttribute的Value属性。如果一个元素只有单个XText子节点…

明朝是中国历史上最有骨气的王朝?【ZZ】

linked from http://www.guoxue.com/article/list.asp?id6095明朝是中国历史上最有骨气的王朝&#xff1f;作者&#xff1a; &#xff08;国学网2006-5-12发布&#xff09; 有人对明朝极尽污蔑之能事&#xff0c;好象明朝是最不中用的朝代。其实&#xff0c;只要细心比较&am…

马哥第七次作业

系统的INPUT和OUTPUT默认策略为DROP&#xff0c;请完成以下关于iptables的题目&#xff1b;1、限制本地主机的web服务器在周一不允许访问&#xff1b;新请求的速率不能超过100个每秒&#xff1b;web服务器包含了admin字符串的页面不允许访问&#xff1b;web服务器仅允许响应报文…

Strategy_Pattern

以下代码是“策略模式”的第四个例子&#xff1a;

JAVA-基础(Class对象及反射)

JAVA-基础&#xff08;Class对象及反射&#xff09; 1.&#xff08;1&#xff09;什么是class对象&#xff1f; 首先&#xff0c;java有两种对象&#xff0c;第一种是实例对象&#xff0c;第二种是Class对象&#xff0c;每一个类运行的类型信息就是用Class对象表示的&#xff0…

当年学生的一件事,心情很难过

当年学生的一件事&#xff0c;心情很难过 今天同一个以前的学生聊天&#xff0c;搞得心情很难过。那年是刚毕业&#xff0c;带了几个学生的毕业论文&#xff0c;其中有一个&#xff0c;只是第一次见过一面&#xff0c;最后答辩前见一两天以及答谢见过一面。他从来不同我联系&am…

while循环中,break,continue,return的差别

break 结束循环&#xff0c;跳出循环体&#xff1b;continue 结束本次循环。进行下次循环&#xff1b;return 跳出循环体所在的方法&#xff0c;相当于跳出循环体。

Strategy_Level2

以下代码是“策略模式”的第五个例子&#xff1a;

自制绘图之坐标轴

写代码之前得先了解坐标轴的一些属性&#xff0c;坐标轴有范围&#xff0c;每隔多少显示一条数值信息。然而间隔信息有时并不确定&#xff0c;一旦设置不准确&#xff0c;图形会乱掉。最好的方法是使用另一个参数&#xff1a;分隔符总数。这样可以利用坐标范围计算出间隔。 首先…

DotNET(C#) Socket基本编程 (1)

Socket基本编程 服务端&#xff1a; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; Thread mythread ; Socket socket; // 清理所有正在使用的资源。 protected override void Dispose( bool disposing ) { try {    socket.Clos…

CC2540 OSAL 学习其中原理,以及 给任务 添加 一个事件(定时发送串口消息)

参考学习大神博客&#xff1a; http://blog.csdn.net/feilusia/article/details/51083953 &#xff1a; http://blog.csdn.net/xiaoleiacmer/article/details/41723583 1、TI 的 CC2540跑了一个 OSAL (Operating System Abstraction Layer) 心得&#xff1a;大概 就是 一个循…

Strategy_Level3

以下代码是“策略模式”的第六个例子&#xff1a;

SDK开发日积月累(二)

WM_NOTIFY消息和WM_COMMAND消息在一个对话框中&#xff0c;子控件可以有两种方式与父对话框通信。1.向父对话框发送WM_COMMAND消息&#xff0c;但这种消息传递的信息量比较少。2.向父对话框发送WM_NOTIFY消息&#xff0c;信息量比较大。idCtrl (int) wParam; pnmh (LPNMHDR) …

关于IP地址的分类

我们说过因特网是把全世界的无数个网络连接起来的一个庞大的网间网&#xff0c;每个网络中的计算机通过其自身的IP地址而被唯一标识的&#xff0c;据此我们也可以设想&#xff0c;在INTERNET上这个庞大的网间网中&#xff0c;每个网络也有自己的标识符。这与我们日常生活中的电…

Visual Studio UML Activity Diagram(1)

数理系LSGO软件技术团队能够存活下来&#xff0c;并形成战斗力的根本原因&#xff0c;归结为我们的价值观。我们“只问收获&#xff0c;不问耕耘”&#xff0c;对知识是贪婪的&#xff0c;我们会把所学的知识放到场景中去应用&#xff0c;我们一定要做出成品。我们强调“要构建…

VMware 克隆Linux后找不到eth0

VMware 克隆Linux,ifconfig 不出现eth0解决方案:1)删除 /etc/udev/rules.d/70-persistent-net.rules/rm -rf /etc/udev/rules.d/70-persistent-net.rules2)重启init 6 3)ifconfig 查看转载于:https://blog.51cto.com/ictedu/1917185

笔试算法题(58):二分查找树性能分析(Binary Search Tree Performance Analysis)

议题&#xff1a;二分查找树性能分析&#xff08;Binary Search Tree Performance Analysis&#xff09; 分析&#xff1a; 二叉搜索树&#xff08;Binary Search Tree&#xff0c;BST&#xff09;是一颗典型的二叉树&#xff0c;同时任何节点的键值大于等于该节点左子树中的所…

定义自定义的异常

首先我们建立自己的异常类CustomException&#xff0c;它要继承自ApplicationException类&#xff08;这是一个在发生非致命的应用程序错误时抛出的通用异常&#xff0c;它又继承于更为通用的Exception类&#xff09;&#xff0c;将其用作为应用程序定义的任何自定义异常的基类…

python3 的 round 函数的 练习

python3 的 round 函数感觉很别扭&#xff0c;其运算结果与习惯不相符。特记录下来&#xff1a; 代码 python 3的 round 函数 是“四舍六入五成双”的https://www.zhihu.com/question/20128906print(python 3的 round 函数&#xff1a;四舍六入五成双)print(\nround(-3.5) , …