笨鸟之Serlvet解析

来源:互联网 发布:java正则表达式 . 编辑:程序博客网 时间:2024/05/17 03:46

Web是当今主流的互联网Web技术,而Servlet是JavaWeb的基础核心。按照自己的理解粗略的记录下了概要内容,以共同学习!


一,以我们所熟悉的Tomcat为例,记录下容器加载的原理知识点。

1,启动Tomcat --> StandardServer ---> StandardService --->StandardEngine(引擎) --->StandardHost--->StandardContext ---> ContextConfig ---> Connector ---> MapperListener

2,一个Web应用就对应一个Context,就创建一个StandardContext,即通常所说的Context容器,也就是Servlet运行时的容器。

3,启动Tomcat后调用Tomcat类的start(),因为Tomcat是基于观察者模式设计的,所有的类都继承自Lifecycle接口,它管理着整个容器的生命周期,所有容器的修改和状态的改变都会通知注册的观察者(Listener),所以当创建StandardContext调用init()时,就出发初始化很重要的配置ContextConfig,这个类负责整个Web工程的解析工作,最终将Context容器添加到Host容器当中。

4,下面就来说说负责整个Web工程解析工作的类ContextConfig。打开源码org.apache.catalina.startup.ContextConfig就可以看到:

· (1)  调用inti()创建用与解析配置文件的contextDigester对象。接下来就是解析context.xml和Host的一些配置文件了,然后设置Context的docBase;

(2)  调用startInteral()来初始化context内部的一些组件,这个类比较复杂,主要包括以下几个部分:

a,创建读取文件资源的对象

b,创建classLoader对象

c,设置应用的工作目录

d,启动相关的辅助类,例如logger等

e,修改启动状态,此时肯定要通知注册的监听者

f ,子容器的初始化工作,为servlet容器设置参数(ServletMapping)到Context容器中,并初始化load-on-startup的Servlet(默认配置了DefaultServletJspServlet),此初始化时调用inti(),设置了ServletConfig,包含了Servlet本身的参数和容器的参数。

(3)  如何启动Web应用呢?调用configureStart(),其实初始化web应用主要就是解析web.xml,web.xml是Web应用的入口。

      在web.xml中配置的Servlet对象、Filter和Listener等都是此时初始化的。

5,在Context容器完成对Web应用的初始化后,容器(Servlet)的引擎StandardEngine会在后台启动一个线程来处理一些定时的操作或监控等。

6,线程启动后,就根据Http请求的url根据MapperListener来分配Servlet容器(ServletContext)。此时问题来?为什么能根据url就能准确的找到相应的Servlet容器呢?这种映射工作专门有个类org.apchae.tomcat.util.Mapper在Http请求request到达Container容器之前,就根据Host和contextpath设置到了mapperData属性中了,当request到container容器时就对应上。

二,Servlet的总结:

1,Servlet来就是普通的java类,只不过它需要在Servlet容器中才能运行,它是个组件供Servlet引擎调用的。

2,了解Serlvet的结构图:

(1) 两个接口Servlet(管理者Servlet的生命周期)和ServletConfig(管理着Servlet和Servlet容器(ServletContext)的参数)。

     在ContextConfig.startInteral()初始化Context的Servlet的组件时就设置了ServletConfig。

(2) Servlet的生命周期:

     init(ServletConfig servletConfig)  --- 只执行一次,初始化时servlet引擎将servletConfig对象传递进来。

     service(ServletRequest,ServletResponse)  ---  在init()执行完之后才会执行。

        在这个方法中HttpServlet中的service()分配Http请求,doGet、doPost、doPut、doDeleted、doHead等7种请求方式。

     destroy() --- 从容器中移除Servlet组件。

     另: getServletConfig()返回init(ServletConfig servletConfig)中的servletConfig对象。

3,GenericServlet和HttpServlet好像作用重合了? 其实HttpServlet主要是负责Http请求的serlvet。

      另外GenericServlet中有重载init()方法的作用? 在有参的init(ServletConfig servletConfig)中调用了init(),方便子类的重写。

4,处理Http请求需要主要几个字段:Last-Modified和If-Modified-Since

在这里有两个HTTP字段需要注意,一个是响应实体首部Last-Modified,表示Servlet的修改时间;一个是请求头部,If-Modified-Since,如果资源在指定的时间之后没有修改过,那么表示缓存有效,可以直接使用缓存。如果HttpServlet.getLastModified()返回-1表示没有缓存。如果返回正数且比If-Modified-Since要新,表示缓存失效了,否则返回304表示用缓存。

 

0 0