Servlet容器

1、Servlet简介

Servlet与Servlet容器是相互依存的,但是又独立发展,这一切是为了适应工业化生产。从技术角度来说是为了解耦,通过标准化接口来相互协作。

在Tomcat容器等级中,Context容器直接管理Servlet在容器中的包装类Wrapper,所以Context容器如何运行将直接影响Servlet的工作方式。

输入图片说明

Tomcat的容器分为4个等级,真正管理Servlet容器的是Context容器,一个Context对应一个Web工程,在Tomcat的配置文件中可以很容易地发现这一点。

2、Servlet容器的启动过程

Tomcat 7也开始支持嵌入式功能,增加一个启动类org.apache.catalina.startup.Tomcat。创建一个实例对象并调用start方法就可以很容易地启动Tomcat。我们还可以通过这个对象来增加和修改Tomcat的配置参数,如可以动态增加Context、Servlet等。下面我们就利用这个Tomcat类来管理一个新增的Context容器,选择Tomcat 7自带的examples Web工程,并看看它是如何加到这个Context容器中的。

Tomcat tomcat = getTomcatInstance();
File appDir = new File(getBuildDirectory(),"webapps/examples");
tomcat.addWebapp(null,"/examples",appDir.getAbsolutePath());
tomcat.start();

一个Web应用对应一个Context容器,也就是Servlet运行时的Servlet容器。添加一个Web应用时将会创建一个StandardContext容器,并且给这个Context容器设置必要的参数,url和path分别代表这个应用在Tomcat中的访问路径和这个应用实际的物理路径,这两个参数与Tomcat配置中的两个参数是一致的。其中最重要的一个配置是ContextConfig,这个类将会负责整个Web应用配置的解析工作,后面将会对其进行详细介绍。最后将这个Context容器加载到父容器Host中。

接下来将会调用Tomcat的start方法启动Tomcat。如果你清楚Tomcat的系统架构,那么会很容易理解Tomcat的启动逻辑。Tomcat的启动逻辑是基于观察者模式设计的,所有的容器都会继承Lifecycle接口,它管理着容器的整个生命周期,所有容器的修改和状态的改变都会由它去通知已经注册的观察者。

当Context容器初始化状态设为init时,添加到Context容器的Listener将会被调用。ContextConfig继承了LifecycleListener接口,他是在调用Tomcat.addWebapp时被加入到StandardContext容器中的。ContextConfig类会负责整改Web应用的配置文件的解析工作。

ContextConfig的init方法将会主要完成以下工作。

  • 创建用于解析XML配置文件的contextDigester对象。
  • 读取默认的context.xml配置文件,如果存在则解析它。
  • 读取默认的host配置文件,如果存在则解析它。
  • 读取默认的Context自身的配置文件,如果存在则解析它。
  • 设置Context的DocBase。

ContextConfig的init方法完成后,Context容器就会执行startInternal方法,这个方法的启动逻辑比较复杂,主要包括如下及部分。

  • 创建读取资源文件的对象。
  • 创建ClassLoader对象。
  • 设置应用的工作目录。
  • 启动相关的辅助类,如logger、realm、resources等。
  • 修改启动状态,通知感兴趣的观察者(Web应用的配置)。
  • 子容器的初始化。
  • 获取ServletContext并设置必要的参数。
  • 初始化“load on startup”的Servlet。

3、Web应用初始化工作

Web应用的初始化工作室在ContextConfig的configureStart方法中实现的,应用的初始化主要是解析web.xml文件,这个文件描述了一个Web应用的关键信息,也就是一个Web。 Tomcat首先会找engine的工作目录下的globalWebXml,接着会找hostWebXml,然后去寻找项目中的web.xml,将此文件中的配置属性保存在WebXml对象中,然后WebXml中的属性和配置会对应到Context容器中,包括创建Servlet对象、filter、listener等。

4、创建Servlet实例

如果Servlet的load-on-startup配置项大于0,那么在Context容器启动时就会被实例化,解析配置文件时会读取默认的globalWebXml,在conf下的web.xml文件中定义了一些默认的配置项,其中定义了两个Servlet,分别是org.apache.catalina.servlets.DefaultServlet和org.apache.jasper.servlet.JspServlet。它们的load-on-startup分别是1和3,也就是当Tomcat启动时这两个Servlet就会被启动。

创建Servlet实例的方法是从Wrapper.loadServlet开始的。loadServlet方法要完成的就是获取ServletClass,然后把它交给InstanceManager去创建一个基于ServletClass.class的对象。如果这个Servlet配置了jsp-file,那么这个ServletClass就是说在conf/web.xml中定义的org.apache.jasper.servlet.JspServlet了。

转载于:https://my.oschina.net/chenxuanli/blog/1529411

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值