一、概述

不管是什么语言开发的web应用程序,都是在解决一个问题,那就是用户输入url怎么把对应的页面响应出来,如何通过url映射到响应的类,由于自己做asp.net的时间也不短了,还算是对asp.net的整个流程还算是了解,所以在自学JavaWeb的时候也很好奇JavaWeb中是如何处理的。

二、asp.net的工作原理

下面的对asp.net的工作流程的介绍(红字)以及我个人的理解。这里也给学asp.net的推荐一本书<<asp.net本质论>>,这本书对http请求流程讲的比较详细,也是一本挺不错的书。

以IIS 6.0为例,在工作进程w3wp.exe中,利用Aspnet_ispai.dll加载.NET运行时(如果.NET运行时尚未加载)。IIS 6引入了应用程序池的概念,一个工作进程对应着一个应用程序池。一个应用程序池可以承载一个或者多个Web应用,每个Web应用映射到一个IIS虚拟目录。与IIS 5.x一样,每一个Web应用运行在各自的应用程序域中。

下图是我本地电脑的IIS应用程序池列表。

上图红线部分也显示的很清楚,应用程序池与工作进程相关联,包含一个或多个应用程序,并提供不同应用之间的隔离。在我本地Test应用池中就有2个应用。具体创建可以参考Nginx负载均衡篇http://www.cnblogs.com/5ishare/p/6129775.html.

如果HTTP.SYS接收到的HTTP请求是对该Web应用的第一次访问,当成功加载了运行时后,会通过AppDomainFactory为该Web应用创建一个应用程序域(AppDomain)。随后,一个特殊的运行时IsapiRuntime被加载。IsapiRuntime定义在程序集System.Web中,对应的命名空间为System.Web.Hosting。IsapiRuntime会接管该HTTP请求。

这里的应用程序域提供了四个重要的机制。

1.隔离  不同应用程序域直接不能直接访问

2.卸载   被加载的应用程序集只能以应用程序域为单位来卸载

3.安全  以应用程序域为边界的安全机制

4.配置  以应用程序域为边界的配置

IsapiRuntime会首先创建一个IsapiWorkerRequest对象,用于封装当前的HTTP请求,并将该IsapiWorkerRequest对象传递给ASP.NET运行时:HttpRuntime,从此时起,HTTP请求正式进入了ASP.NET管道。根据IsapiWorkerRequest对象,HttpRuntime会创建用于表示当前HTTP请求的上下文(Context)对象:HttpContext。

IsapiWorkerRequest是比较底层的对象,HttpRuntime接到请求之后会将其分析拆解,创建HttpRequest、HttpResponse对象,一次Http请求需要好几个对象,还有HttpServerUtility类型的对象处理网站虚拟路径和服务器文件系统之间的映射关系,为了管理这些对象,定义了HttpContext来统一处理参数的表示问题。

随着HttpContext被成功创建,HttpRuntime会利用HttpApplicationFactory创建新的或者获取现有的HttpApplication对象。实际上,ASP.NET维护着一个HttpApplication对象池,HttpApplicationFactory从池中选取可用的HttpApplication用户处理HTTP请求,处理完毕后将其释放到对象池中。HttpApplicationFactory负责处理当前的HTTP请求。HttpRuntime创建HttpContext成功之后,会创建HttpApplication对象,需要注意的是HttpApplication对象创建的来源,一是通过HttpApplicationFactory创建一种是HttpApplication对象池获取,它和Java Web中可不太一样。JavaWeb中的Servlet是单例多线程,通过Servlet对象只创建一个,通过线程池来响应请求。

在HttpApplication初始化过程中,会根据配置文件加载并初始化相应的HttpModule对象。对于HttpApplication来说,在它处理HTTP请求的不同的阶段会触发不同的事件(Event),而HttpModule的意义在于通过注册HttpApplication的相应的事件,将所需的操作注入整个HTTP请求的处理流程。ASP.NET的很多功能,比如身份验证、授权、缓存等,都是通过相应的HttpModule实现的。

当请求转入ASP.NET管道后,最终负责处理该请求的是与请求资源类型相匹配的HttpHandler对象,但是在Handler正式工作之前,ASP.NET会先加载并初始化所有配置的HttpModule对象。HttpModule在初始化的过程中,会将一些功能注册到HttpApplication相应的事件中,那么在HttpApplication整个请求处理生命周期中的某个阶段,相应的事件会被触发,通过HttpModule注册的事件处理程序也得以执行。所有的HttpModule都实现了IHttpModule接口。

这里的HttpModule起到了过滤的功能,这就和JavaWeb的Filter有点类型,利用它们可以做一些例如权限等一些处理。这种设计的好处也很明显,扩展性很强,用户可以自己选择使用。

而最终完成对HTTP请求的处理实现在另一个重要的对象中:HttpHandler。对于不同的资源类型,具有不同的HttpHandler。比如.aspx页对应的HttpHandler为System.Web.UI.Page,WCF的.svc文件对应的HttpHandler为System.ServiceModel.Activation.HttpHandler。

HttpHander有点类似JavaWeb的Servlet,最终处理还是需要它们,而且都是web的基础,JavaWeb中jsp最终还是会以Servlet对象来运行,asp.net中也是一样。

三、JavaWeb的工作流程

上面asp.net主要是关于池子的问题,下面JavaWeb主要是关于容器的问题。

Tomcat 的容器分为四个等级,真正管理 Servlet 的容器是 Context 容器,一个 Context 对应一个 Web 工程。这里有点类似asp.net的应用程序域。

一个 Web 应用对应一个 Context 容器,也就是 Servlet 运行时的 Servlet 容器,添加一个 Web 应用时将会创建一个 StandardContext 容器,并且给这个 Context 容器设置必要的参数。最重要的一个配置是 ContextConfig,这个类将会负责整个 Web 应用配置的解析工作,最后将这个 Context 容器加到父容器 Host 中。

1.其实我们在用eclipse将工程添加到tomcat服务器的过程就是在执行上面的工作。注意下面红线的部分,If server is started,publish changes immediately.服务器启动时,对Context 容器做的改变会立刻发布。能做到立刻发布,主要是靠观察者设计模式的Listener。ContextConfig 继承了 LifecycleListener 接口,所以对ContextConfig的修改也会立刻生效。

2.ContextConfig对象

关于ContextConfig对象,我们可以逆向的思考,我们创建一个Servlet类的同时需要在web.xml中进行配置servlet-name、servlet-calss、servlet-mapping、init-param,那Context容器又是怎么知道它们的对应关系和初始化参数呢?于是ContextConfig出现了。找到了这么多的初始化参数和映射关系,通过这些参数和映射将Servlet、Filter、Listener放入容器中,

3.Servlet实例化、初始化

上面虽然通过ContextConfig将Servlet各个初始化属性添加到Context容器中,但并没有将Servlet进行实例化初始化,所以还是不能使用。如果 Servlet 的 load-on-startup 配置项大于 0,那么在 Context 容器启动的时候就会被实例化。而实例化就要找到对应的类,对于jsp文件实质也是Servlet,servletClass 就是 conf/web.xml 中定义的 org.apache.jasper.servlet.JspServlet。而Servlet对象只会创建、初始化一次,如果有多个请求同时访问,会从线程池中获取一个线程还是用这个Servlet对象处理用户请求,算是单例多线程,这就会带来一个问题,线程安全问题,访问特别是修改Servlet类中的全局变量时会导致数据错误,所以尽量不使用在Servlet类中声明全局变量。实在不行就需要给线程加锁。

4.Servlet的生命周期

生命周期这个词在开发中很常见,Servlet也不例外。

Servlet 生命周期:Servlet 加载--->实例化(init())--->服务(Service())--->销毁(destroy())。

加载和实例化已在tomcat启动的时候完成,当客户端发起请求,Servlet是调用service()方法对请求进行响应的,service()方法中对请求的方式进行了匹配,选择调用doGet,doPost等这些方法,然后再进入对应的方法中调用逻辑层的方法,实现对客户的响应.

destroy(): 仅执行一次,在服务器端停止且卸载Servlet时执行该方法。当Servlet对象退出生命周期时,负责释放占用的资源。一个Servlet在运行service()方法时可能会产生其他的线程,因此需要确认在调用destroy()方法时,这些线程已经终止或完成.

5.Servlet的继承关系

我们创建的每一次Servlet都是继承abstract HttpServlet,而HttpServlet 又继承了javax.servlet.GenericServlet。GenericServlet是一个通用的,不特定于任何协议的Servlet,它实现了Servlet接口.

Servlet接口和GenericServlet是不特定于任何协议的,而HttpServlet是特定于HTTP协议的类,所以HttpServlet中实现了service()方法,并将请求ServletRequest、ServletResponse 强转为HttpRequest 和 HttpResponse。

Java与.NET机制比较分析的更多相关文章

  1. Java虚拟机类加载机制——案例分析

    转载: Java虚拟机类加载机制--案例分析   在<Java虚拟机类加载机制>一文中详细阐述了类加载的过程,并举了几个例子进行了简要分析,在文章的最后留了一个悬念给各位,这里来揭开这个悬 ...

  2. 【转载】Java虚拟机类加载机制与案例分析

    出处:https://blog.csdn.net/u013256816/article/details/50829596 https://blog.csdn.net/u013256816/articl ...

  3. [转]Java虚拟机类加载机制

    原文地址:http://blog.csdn.net/u013256816/article/details/50829596 看到这个题目,很多人会觉得我写我的java代码,至于类,JVM爱怎么加载就怎 ...

  4. Java 类反射机制分析

    Java 类反射机制分析 一.反射的概念及在Java中的类反射 反射主要是指程序可以访问.检测和修改它本身状态或行为的一种能力.在计算机科学领域,反射是一类应用,它们能够自描述和自控制.这类应用通过某 ...

  5. Java 动态代理机制分析及扩展

    Java 动态代理机制分析及扩展,第 1 部分 王 忠平, 软件工程师, IBM 何 平, 软件工程师, IBM 简介: 本文通过分析 Java 动态代理的机制和特点,解读动态代理类的源代码,并且模拟 ...

  6. [转]Java 动态代理机制分析及扩展

    引言 Java 动态代理机制的出现,使得 Java 开发人员不用手工编写代理类,只要简单地指定一组接口及委托类对象,便能动态地获得代理类.代理类会负责将所有的方法调用分派到委托对象上反射执行,在分派执 ...

  7. 【JVM】深度分析Java的ClassLoader机制(源码级别)

    原文:深度分析Java的ClassLoader机制(源码级别) 为了更好的理解类的加载机制,我们来深入研究一下ClassLoader和他的loadClass()方法. 源码分析 public abst ...

  8. Java 动态代理机制分析及扩展--转

    http://www.ibm.com/developerworks/cn/java/j-lo-proxy1/#icomments http://www.ibm.com/developerworks/c ...

  9. Java 动态代理机制分析及扩展,第 1 部分

    Java 动态代理机制分析及扩展,第 1 部分 http://www.ibm.com/developerworks/cn/java/j-lo-proxy1/ 本文通过分析 Java 动态代理的机制和特 ...

随机推荐

  1. Java笔记8:Hibernate连接Oracle

    1下载hibernate-3.6.0 Final.zip到任意目录,解压缩后得到hibernate目录 2下载slf4j-1.7.13.zip到任意目录,解压缩后得到slf4j-1.7.13 3操作数 ...

  2. Razor语法(三)

    1.定义变量 定义变量或声明常量必须在代码体内,代码体以'@{'开头,以'}'结束,其中定义变量以'var'进行声明.代码体内每行以';'做为结束标识. @{       var i = 10;    ...

  3. 怎样删除Weblogic Domain?

    转自:http://blog.csdn.net/biplusplus/article/details/7433558 旁白 由于没有现成的配置工具可以做这件事,我们需要手工来删除. 正题 以下方法适用 ...

  4. zookeeper伪分布式集群安装

    1.安装3个zookeeper 1.1创建集群安装的目录 1.2配置一个完整的服务 这里不做详细说明,参考我之前写的 zookeeper单节点安装 进行配置即可,此处直接复制之前单节点到集群目录 创建 ...

  5. 下载论坛源码GBK UTF8 BIG5分别是什么意思

    下载论坛源码GBK UTF8 BIG5分别是什么意思? 提问者:ly1987520 | 浏览次数:4010次 下载论坛源码简体中文GBK 简体中文UTF8 繁体中文BIG5 分别是什么意思?他们的区别 ...

  6. JMeter 五:监控服务器

    参考:http://jmeter.apache.org/usermanual/build-monitor-test-plan.html 添加Thread Group 添加方法:Test Plan上右键 ...

  7. iOS程序发布测试-生成ad hoc证书

    转自: http://blog.sina.com.cn/s/blog_68444e230100srdn.html iOS程序发布测试3-生成ad hoc证书 iOS证书分2种,1种是开发证书,用来给你 ...

  8. 算法笔记_088:蓝桥杯练习 8-1因式分解(Java)

    目录 1 问题描述 2 解决方案   1 问题描述 问题描述 设计算法,用户输入合数,程序输出若个素数的乘积.例如,输入6,输出2*3.输入20,输出2*2*5. 样例 与上面的样例输入对应的输出. ...

  9. push和unshift方法

    push和unushift都是向数组插入元素. push是向数组尾部插入元素. unshift是向数组头部插入元素. 共同点:都可以一次插入多个元素. arrayObject.push(newelem ...

  10. jquery 实现菜单的下拉菜单

    实现效果如图: 源码: 到此下载