Tomcat当中在接受到要调用的Servlet请求后,需要载入相应的Servlet类,然后创建Servlet类实例,从而调用Servlet类实例的service()方法

下面实例的场景,request和response分别是一个javax.servlet.ServletRequest实例和一个javax.servlet.ServletResponse实例,request通过getUri()方法从ServletRequest当中获取uri

uri格式为/servlet/servletName

其中servletName就是所请求servlet资源的类名,针对这个资源名,调用URLClassLoader类载入相应的类实例

public void process(Request request, Response response)
{ String uri = request.getUri();
String servletName = uri.substring(uri.lastIndexOf("/") + 1);
URLClassLoader loader = null; try
{
// create a URLClassLoader
URL[] urls = new URL[1];
URLStreamHandler streamHandler = null;
File classPath = new File(Constants.WEB_ROOT);
// the forming of repository is taken from the createClassLoader
// method in
// org.apache.catalina.startup.ClassLoaderFactory
String repository = (new URL("file", null, classPath.getCanonicalPath() + File.separator)).toString();
// the code for forming the URL is taken from the addRepository
// method in
// org.apache.catalina.loader.StandardClassLoader class.
urls[0] = new URL(null, repository, streamHandler);
loader = new URLClassLoader(urls);
} catch (IOException e)
{
System.out.println(e.toString());
}
Class myClass = null;
try
{
myClass = loader.loadClass(servletName);
} catch (ClassNotFoundException e)
{
System.out.println(e.toString());
} Servlet servlet = null; try
{
servlet = (Servlet) myClass.newInstance();
servlet.service((ServletRequest) request, (ServletResponse) response);
} catch (Exception e)
{
System.out.println(e.toString());
} catch (Throwable e)
{
System.out.println(e.toString());
} }

使用java.net.URLClassLoader类来完成,该类是java.lang.ClassLoader类的一个直接子类,一旦创建了URLClassLoader类的实例之后,就可以使用它的loadClass()方法来载入Servlet类,实例化URLClassLoader类有三种方法,也就是有三个构造方法

构造方法摘要
URLClassLoader(URL[] urls)
使用默认的委托父 ClassLoader 为指定的 URL 构造一个新
URLClassLoader。
URLClassLoader(URL[] urls, ClassLoader parent)

为给定的 URL 构造新 URLClassLoader。
URLClassLoader(URL[] urls, ClassLoader parent, URLStreamHandlerFactory factory)

为指定的 URL、父类加载器和 URLStreamHandlerFactory 创建新 URLClassLoader。
URLClassLoader

参数:
urls - 从其位置加载类和资源的 URL
抛出:
SecurityException - 如果安全管理器存在并且其 checkCreateClassLoader 方法不允许创建类加载器。
另请参见:
SecurityManager.checkCreateClassLoader()

public URLClassLoader(URL[] urls)使用默认的委托父 ClassLoader 为指定的 URL 构造一个新 URLClassLoader。\n
首先在父类加载器中搜索 URL,然后按照为类和资源指定的顺序搜索 URL。这里假定任何以 '/' 结束的 URL 都是指向目录的。\n
如果不是以该字符结束,则认为该 URL 指向一个将根据需要下载和打开的 JAR 文件。
如果有安全管理器,该方法首先调用安全管理器的 checkCreateClassLoader 方法以确保允许创建类加载器。

参数中urls是一个java.net.URL  对象数组,当载入一个类时每个URL对象都指明了类载入器要到哪里查找类。

若一个URL以“/”结尾,则表明它指向的是个目录,否则,URL默认指向一个JAR文件,根据需要载入器会下载并打开这个JAR文件。

在这个例子当中,类载入器只需要查找一个位置,即工作目录下的webroot目录,因此,需要先创建一个只有一个URL对象的数组。

URL类提供了一系列的构造函数,因此有很多方法可以创建URL对象。

  
URL
public URL(URL context,
String spec,
URLStreamHandler handler)
throws MalformedURLException通过在指定的上下文中用指定的处理程序对给定的 spec 进行解析来创建 URL。如果处理程序为 null,则使用两参数构造方法进行解析。 参数:
context - 要在其中解析规范的上下文。
spec - 将作为 URL 解析的 String。
handler - URL 的流处理程序。
抛出:
MalformedURLException - 如果未指定任何协议,或者找到了未知协议。
SecurityException - 如果安全管理器存在并且其 checkPermission 方法不允许指定流处理程序。
另请参见:
URL(java.lang.String, java.lang.String, int, java.lang.String), URLStreamHandler, URLStreamHandler.parseURL(java.net.URL, java.lang.String, int, int)

可以将第二个参数指定为一个目录,指定第一个和第三个参数为null,这样就可以使用构造函数了,但是我们看到在URL当中,还有一个构造函数,它也接受三个参数,

URL
public URL(String protocol,String host,String file) throws MalformedURLException

根据指定的 protocol 名称、host 名称和 file 名称创建 URL。使用指定协议的默认端口。
此方法等同于调用带四个参数的构造方法,四个参数为 protocol、host、-1 和 file。 此构造方法不执行对输入的验证。

参数:
protocol - 要使用的协议名称。
host - 主机名称。
file - 主机上的文件。
抛出:
MalformedURLException - 如果指定了未知协议。
另请参见:
URL(java.lang.String, java.lang.String, int, java.lang.String)

所以为了编译器的区别,指明第三个参数的类型

URLStreamHandler streamHandler = null;

new URL(null,aString,streamHandler);

第二个参数中的字符串指明了仓库的路径,也就是查找servlet类的目录。可以使用下面的代码生成仓库

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

使用URLClassLoader类载入类实例的更多相关文章

  1. Java类载入器 ClassLoader的解析

    //參考 : http://www.ibm.com/developerworks/cn/java/j-lo-classloader/ 类载入器基本概念 类载入器是 Java 语言的一个创新,也是 Ja ...

  2. Jetty 类载入问题处理

    前几日使用 Jetty (9.2)部署公司一个 web 项目,这个项目原本部署在 Tomcat server上,一切正常,可是部署到 Jetty 后,启动报错.关键错误信息为"java.la ...

  3. 深入研究Java类载入机制

    深入研究Java类载入机制   类载入是Java程序运行的第一步,研究类的载入有助于了解JVM运行过程,并指导开发人员採取更有效的措施配合程序运行. 研究类载入机制的第二个目的是让程序能动态的控制类载 ...

  4. Tomcat类载入器机制(Tomcat源代码解析六)

    要说Tomcat的Classloader机制,我们还得从Bootstrap開始.在BootStrap初始化的时候.调用了org.apache.catalina.startup.Bootstrap#in ...

  5. Atitti 载入类的几种方法    Class.forName ClassLoader.loadClass  直接new

    Atitti 载入类的几种方法    Class.forName ClassLoader.loadClass  直接new 1.1. 载入类的几种方法    Class.forName ClassLo ...

  6. JVM系列文章(四):类载入机制

    作为一个程序猿,只知道怎么用是远远不够的. 起码,你须要知道为什么能够这么用.即我们所谓底层的东西. 那究竟什么是底层呢?我认为这不能一概而论.以我如今的知识水平而言:对于Web开发人员,TCP/IP ...

  7. 利用java反射机制 读取配置文件 实现动态类载入以及动态类型转换

    作者:54dabang 在spring的学习过程之中,我们能够看出通过配置文件来动态管理bean对象的优点(松耦合 能够让零散部分组成一个总体,而这些总体并不在意之间彼此的细节,从而达到了真正的物理上 ...

  8. 具体解释Java虚拟机类载入

    概述 在Java语言里面,类型的载入.连接和初始化过程都是在程序运行期间完毕的.虚拟机把描写叙述类的数据从Class文件或其他地方载入到内存,并对数据进行校验.转换解析和初始化,终于形成能够被虚拟机直 ...

  9. Android执行时ART载入类和方法的过程分析

    在前一篇文章中.我们通过分析OAT文件的载入过程,认识了OAT文件的格式,当中包括了原始的DEX文件. 既然ART运行时运行的都是翻译DEX字节码后得到的本地机器指令了.为什么还须要在OAT文件里包括 ...

随机推荐

  1. Android 中 更新视图的函数ondraw() 和dispatchdraw()的区别

    绘制VIew本身的内容,通过调用View.onDraw(canvas)函数实现 绘制自己的孩子通过dispatchDraw(canvas)实现 View组件的绘制会调用draw(Canvas canv ...

  2. java -Xmx3550m -Xms3550m -Xmn2g -Xss128k

    java -Xmx3550m -Xms3550m -Xmn2g -Xss128k1.-Xmx3550m:设置JVM最大可用内存为3550M.2.-Xms3550m:设置JVM促使内存为3550m.此值 ...

  3. Java基础知识强化之集合框架笔记52:Map集合之Map集合的遍历 键找值

    1. Map集合的遍历  Map -- 夫妻对 思路:  A:把所有的丈夫给集中起来.  B:遍历丈夫的集合,获取得到每一个丈夫.  C:让丈夫去找自己的妻子.  转换:  A:获取所有的键  B:遍 ...

  4. 256MB小内存MySQL配置优化

    [client] port = 3306 socket = /var/run/mysqld/mysqld.sock [mysqld_safe] socket = /var/run/mysqld/mys ...

  5. http://bbs.phpcms.cn/thread-266337-1-1.html

    http://bbs.phpcms.cn/thread-266337-1-1.html utf8  改成 ANSI”

  6. sql like '%x%'优化

    好久没写点什么了.唉(此处省略无数,一切尽在苦逼中...) 说说sql中的全匹配优化吧.在sql server进行模糊查询的时候,如果是进行全匹配的话,那么肯定会用到like.我们知道like '%张 ...

  7. file的name值

    在picturelibrary中取一张jpg文件, 其Name值为  "NoThumbnail.jpg",注意后面的.jpg             foreach (SPFile ...

  8. android - DefaultHttpClient设置超时.

    Android的DefaultHttpClient中,超时设置需要调用HttpConnectionParams.setConnectionTimeout方法,如(以下代码的31~35行代码): ref ...

  9. while loading persisted sessions 异常解决方法

    一直用tomcat一段时间都正常无事,最近一次启动tomcat就发生以下异常: 严重: IOException while loading persisted sessions: java.io.EO ...

  10. 菜鸟日记之 java中的集合框架

    java中的集合框架图 如图所示:java中的集合分为两种Collection和Map两种接口 可分为Collection是单列集合和Map的双列集合 Collection单列集合:继承了Iterat ...