问题1:tomcat什么时候加载servlet?

有两种情况

一种是启动时加载

一种是请求时加载

第一种是在web.xml中的<servlet>节点下增加类似:<load-on-startup>1</load-on-startup>的节点

例子如下:

<servlet>

<servlet-name>DicDataIniter</servlet-name>

<servlet-class>com.init.DicDataIniter</servlet-class>

<load-on-startup>2</load-on-startup>

</servlet>

<servlet-mapping>

<servlet-name>DicDataIniter</servlet-name>

<url-pattern>/DicDataIniter</url-pattern>

</servlet-mapping>

关于load-on-startup,需要了解的是:

1)load-on-startup元素标记容器是否在启动的时候就加载这个servlet(实例化并调用其init()方法)。2)它的值必须是一个整数,表示servlet应该被载入的顺序2)当值为0或者大于0时,表示容器在应用启动时就加载并初始化这个servlet;3)当值小于0或者没有指定时,则表示容器在该servlet被选择时才会去加载。4)正数的值越小,该servlet的优先级越高,应用启动时就越先加载。5)当值相同时,容器就会自己选择顺序来加载。所以,<load-on-startup>x</load-on-startup>,中x的取值1,2,3,4,5代表的是优先级

第二种的流程类似如下图:

问题2:tomcat是怎么加载一个servlet类的呢?

根据上篇对一个简单的webServer模拟(How Tomcat Works 学习-我们到底能走多远系列(8)),在到达"加载servlet类,实例化一个servlet实例"这一步之前的工作我们已经完成了。我们已经取得了来自http消息中的uri,也就已经取得了需要调用的servlet的名字。

根据《How tomcat works》,先搞一个自己的servlet:没什么逻辑,只是生成class文件放到指定的文件夹下等待加载。

package code.tomcat.servletContainer;import java.io.IOException;import java.io.PrintWriter;import javax.servlet.*;public class PrimitiveServlet implements Servlet{

public void init(ServletConfig config) throws ServletException {

System.out.print("init");

}

public ServletConfig getServletConfig() {

return null;

}

// 一旦实现了service方法那么就不会就不会调用父类的service方法从而调用doGet或doPost

public void service(ServletRequest req, ServletResponse res)

throws ServletException, IOException {

System.out.print("service");

PrintWriter writer = res.getWriter();

writer.println("Hello. Roses are red.");

}

public String getServletInfo() {

return null;

}

public void destroy() {

System.out.print("destroy");

}}

加载方法如下:

package code.tomcat.servletContainer;import java.io.File;import java.io.IOException;import java.net.MalformedURLException;import java.net.URL;import java.net.URLClassLoader;import java.net.URLStreamHandler;import javax.servlet.Servlet;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;public class ServletProcessor1 {

public void process(Request request, Response response){

// 取得request处理好的uri

String uri = request.getUri();

// servlet 类名

String servletName = uri.substring(uri.indexOf("/") + 1);

// 类加载器,利用提供的url目录来加载class文件,大多数情况下我们的程序在jvm启动的已经有类加载器加载我们需要的类文件。

// 但是最为需要及时部署的服务器-servlet容器,需要自己去加载放到服务器的工程

URLClassLoader loader = null;

// URLClassLoader构造函数需要URL数组,这里是需要加载一个类

URL[] urls = new URL[1];

// 构造URL用,虽然是null,但如果直接在URL中直接用null来代替,编译器不答应啊

URLStreamHandler streamHandler = null;

File classPath = new File("/webroot");

try {

// servlet文件夹位置

String repository = (new URL("file", null, classPath.getCanonicalPath() + File.separator))。toString();

urls[0] = new URL(null, repository, streamHandler);

// 得到传说中的类加载器

loader = new URLClassLoader(urls);

} catch (MalformedURLException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

// .class文件加载后就是java中的Class类实例啦

Class myClass = null;

try {

// servlet Class类实例

myClass = loader.loadClass(servletName);

} catch (ClassNotFoundException e) {

e.printStackTrace();

}

Servlet servlet = null;

try {

// 用newInstance方法得到一个servlet实例

servlet = (Servlet)myClass.newInstance();

// 调用PrimitiveServlet的service方法

servlet.service((ServletRequest)request, (ServletResponse)response);

} catch (Exception e) {

System.out.println(e.toString());

}

}}

如此,servlet流程中的初始加载这一步就可以勉强完成了,tomcat中的实现要复杂很多吧,原理基本是差不多了,先打下基础。

关于类加载:

其实tomcat启动的时候就有大量的类加载工作需要做,应为tomcat本身就是个java工程嘛。

------------

System.getProperty:

有个类似写日志的方法:

/**

* 写日志

* @param logString

* @throws IOException

*/

public void writeLog(String logString) throws IOException {

File logFile = new File("d:\\我的文档\\test.log");

// 写

FileWriter writer = new FileWriter(logFile,true);

// 取得回车符号

String nextLine = System.getProperty("line.separator");

writer.write(logString + nextLine);

writer.flush();

writer.close();

}

其中System.getProperty("line.separator")方法,值得熟悉。

我们可以通过这样的方式取得一些System级别的常量。

java.version Java 运行时环境版本java.vendor Java 运行时环境供应商java.vendor.url Java 供应商的 URLjava.home Java 安装目录java.vm.specification.version Java 虚拟机规范版本java.vm.specification.vendor Java 虚拟机规范供应商java.vm.specification.name Java 虚拟机规范名称java.vm.version Java 虚拟机实现版本java.vm.vendor Java 虚拟机实现供应商java.vm.name Java 虚拟机实现名称java.specification.version Java 运行时环境规范版本java.specification.vendor Java 运行时环境规范供应商java.specification.name Java 运行时环境规范名称java.class.version Java 类格式版本号java.class.path Java 类路径java.library.path 加载库时搜索的路径列表java.io.tmpdir 默认的临时文件路径java.compiler 要使用的 JIT 编译器的名称java.ext.dirs 一个或多个扩展目录的路径os.name 操作系统的名称os.arch 操作系统的架构os.version 操作系统的版本file.separator 文件分隔符(在 UNIX 系统中是"/")path.separator 路径分隔符(在 UNIX 系统中是":")line.separator 行分隔符(在 UNIX 系统中是"/n")user.name 用户的账户名称user.home 用户的主目录user.dir 用户的当前工作目录

Tomcat加载servlet类文件的更多相关文章

  1. Tomcat启动时自动加载一个类

    有时候在开发Web应用的时候,需要tomcat启动后自动加载一个用户的类,执行一些初始化方法,如从数据库中加载业务字典到内存中,因此需要在tomcat启动时就自动加载一个类,或运行一个类的方法. 可以 ...

  2. 修改类不用重启Tomcat加载整个项目

    可以修改类不用重启Tomcat加载整个项目(手工启动) 配置reloadable=true(自动重载) 使用Debug模式,前提是仅限于局部修改.(修改类不用重启--热加载) Tomcat轻小,而We ...

  3. 如何在tomcat启动时自动加载一个类

    有时候在开发web应用的时候,需要tomcat启动后自动加载一个用户的类,执行一些初始化方法,如从数据库中加载业务字典到内存中,因此需要在tomcat启动时就自动加载一个类,或运行一个类的方法. 可以 ...

  4. mac下 安装tomcat 后项目无法启动以及 错误 找不到或无法加载主类

    按照网上的步骤,在mac上安装tomcat后,写个简单的测试类报错:错误 找不到或无法加载主类 Class JavaLaunchHelper is implemented in both /Libra ...

  5. tomcat启动时自动加载一个类 MyServletContextListener

    目的: 我们知道在tomcat启动后,需要页面请求进行驱动来执行操作接而响应.我们希望在tomcat启动的时候能够自动运行一个后台线程,以处理我们需要的一些操作.因此需要tomcat启动时就自动加载一 ...

  6. 速战速决 (5) - PHP: 动态地创建属性和方法, 对象的复制, 对象的比较, 加载指定的文件, 自动加载类文件, 命名空间

    [源码下载] 速战速决 (5) - PHP: 动态地创建属性和方法, 对象的复制, 对象的比较, 加载指定的文件, 自动加载类文件, 命名空间 作者:webabcd 介绍速战速决 之 PHP 动态地创 ...

  7. Tomcat启动时自动加载Servlet

    1.想做一个服务启动时自动启动一不停止的获取订阅功能 2.之前是做一个Jsp页面请求servlet来触发方法 3.现在实现Tomcat启动时自动加载Servlet 1.Tomcat中启动Servlet ...

  8. PHP加载另一个文件类的方法

    加载另一个文件类的方法 当前文件下有a.php 和b.php,想要在class b中引入class a <?php    class a    {        public $name = ' ...

  9. 运行.class文件提示找不到或者无法加载主类原因

    在Java初学之时,用文本文件写了一个“hello world”的简单程序.在dos环境下使用命令javac -test1.java 进行编译. 编译出名称为test1.class的Java运行文件. ...

随机推荐

  1. nginx - KeepAlive详细解释

    最近工作中遇到一个问题,想把它记录下来,场景是这样的: 从上图可以看出,用户通过Client访问的是LVS的VIP, VIP后端挂载的RealServer是Nginx服务器. Client可以是浏览器 ...

  2. OpenCV2马拉松第15圈——边缘检測(Laplace算子,LOG算子)

    收入囊中 拉普拉斯算子 LOG算子(高斯拉普拉斯算子) OpenCV Laplacian函数 构建自己的拉普拉斯算子 利用拉普拉斯算子进行图像的锐化 葵花宝典 在OpenCV2马拉松第14圈--边缘检 ...

  3. Mac 常用属性

    如果需要让隐藏的文件可见. 具体做法就是打开一个Terminal终端窗口,输入以下命令: 对于OS X Mavericks 10.9: defaults write com.apple.finder ...

  4. python 基础 1.6 python 帮助信息及数据类型间相互转换

      一. 帮助信息   # dir() 方法  查看函数的方法   # help()   # type() 查看类型   name = raw_input('please input you name ...

  5. 升级webapi依赖的Newtonsoft.json的版本(转)

    随着微软日渐重视开源社区的贡献,微软在自己的产品中往往也会集成开源的第三方库. 比如System.Net.Http.Foramatting.dll 就依赖于Newtonsoft.json v4.5. ...

  6. sed 和awk结合取ip 地址

    1.打印文件的第一列(域)                 : awk '{print $1}' filename 2.打印文件的前两列(域)                 : awk '{prin ...

  7. 【Leetcode-easy】Remove Nth Node From End of List

    思路1:设置两个指针p1,p2指向表头,p1先走n步.再两个指针同时走.当p1指针指到链表尾部时,P2指针已经在需要删除节点的前一位.一定要注意一些细节. class ListNode { int v ...

  8. TensorFlow Action(开山使用篇)

    1.TensorFlow安装: 使用pip install tensorflow安装CPU版: 或使用pip install tensorflow-gpu==1.2.1指定版本安装GPU版. 2.Te ...

  9. uboot 从sd卡加载文件并烧写到nand flash

    uboot下可以从用tftp和nfs加载文件. 但是现在有个开发板配套uboot网络功能出现异常,执行ping命令就会导致开发板重启,只能选择先从sd卡加载文件 启动开发板,任意键进入uboot,然后 ...

  10. poj 1146 ID Codes (字符串处理 生成排列组合 生成当前串的下一个字典序排列 【*模板】 )

    ID Codes Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 6229   Accepted: 3737 Descript ...