博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Tomcat学习笔记(七)
阅读量:5021 次
发布时间:2019-06-12

本文共 4580 字,大约阅读时间需要 15 分钟。

 

  Tomcat载入器(一)

       在了解tomcat的载入器时,首先需要了解的是java的类加载部分的内容。

         在java体系中,系统分为3中类型的加载器

         1.启动类加载器(Bootstrap ClassLoader):加载对象为java核心库,采用c/c++实现,并不继承java.lang.ClassLoader,负责加载java_home/jre/lib目录下的类库,同时也属于JVM的一部分,在JVM启动时,将被加载到内存中。启动类加载器不能被java程序直接使用。

         2.扩张类加载器(Extension ClassLoader): 加载对象为java扩张库,即java_home/jre/lib/ext目录下面的类,这个类由启动类加载器加载,它的父类加载器为启动类加载器。

         3.应用程序类加载器(Application ClassLoader):也成为系统类加载器(System ClassLoader)它负责加载用户路径(classpath)指定的类库,它也是有启动类加载器加载,它的父类加载被设置为启动类加载器,可以通过ClassLoader.getSystemClassLoader()获取。

                                                                  

          tip:启动类加载器是扩展类加载器的父类加载器,并不是继承关系。

          越重要的类加载器就越早被载入JVM,这是考虑到安全性,因为先加载的类加载会充当下一个类加载器的父类加载器,在双亲委托模型机制下,就能确保安全性。双亲委托模型会在类加载加载类时,首先委托父类加载器进行加载,如果父类加载器不能加载,才自己加载。这种机制有效的保证java的安全。

        类加载的流程图。

                                                                       

下面用2个例子实现自定义的类加载器。

    1.采用JVM的双亲委托机制实现。

     测试类: Test.java

    

package com.test.load;public class Test {       public Test(){        System.out.println(this.getClass().getClassLoader().toString());    }}

   MyClassLoader.java

import java.io.ByteArrayOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;public class MyClassLoader extends ClassLoader{    private String name;        public MyClassLoader(ClassLoader parent, String name)    {        super(parent);        this.name = name;    }    @Override    public String toString()    {        return "test:::"+this.name;    }        @Override    protected Class
findClass(String name) throws ClassNotFoundException { InputStream is = null; byte[] data = null; ByteArrayOutputStream baos = new ByteArrayOutputStream(); try { is = new FileInputStream(new File("F:/work/web/Test.class")); int c = 0; while(-1 != (c = is.read())){ baos.write(c); } data = baos.toByteArray(); } catch (Exception e) { e.printStackTrace(); }finally{ try { is.close(); baos.close(); } catch (IOException e) { e.printStackTrace(); } } return this.defineClass(name, data, 0, data.length); } public static void main(String[] args) { MyClassLoader loader = new MyClassLoader(MyClassLoader.class.getClassLoader(), "MyClassLoader"); Class clazz; try { clazz = loader.loadClass("com.test.load.Test"); Object object = clazz.newInstance(); } catch (Exception e) { e.printStackTrace(); } }}

2.采用打破委托机制。

public class MyClassLoader2 extends ClassLoader{    private String name;        public MyClassLoader2(ClassLoader parent, String name)    {        super(parent);        this.name = name;    }    @Override    public String toString()    {        return "test2:::"+this.name;    }    @Override    public Class
loadClass(String name) throws ClassNotFoundException { Class
clazz = null; ClassLoader systemLoader = getSystemClassLoader(); try { //打破委托机制 clazz = systemLoader.loadClass(name); } catch (Exception e) { //忽略错误 //e.printStackTrace(); } if(clazz != null) return clazz; //自己加载 clazz = findClass(name); return clazz; } @Override public Class
findClass(String name) throws ClassNotFoundException { InputStream is = null; byte[] data = null; ByteArrayOutputStream baos = new ByteArrayOutputStream(); try { is = new FileInputStream(new File("F:/work/web/Test.class")); int c = 0; while(-1 != (c = is.read())){ baos.write(c); } data = baos.toByteArray(); } catch (Exception e) { e.printStackTrace(); }finally{ try { is.close(); baos.close(); } catch (IOException e) { e.printStackTrace(); } } return this.defineClass(name, data, 0, data.length); } public static void main(String[] args) { MyClassLoader2 loader = new MyClassLoader2(MyClassLoader2.class.getClassLoader(), "MyClassLoader2"); Class clazz; try { clazz = loader.loadClass("com.test.load.Test"); Object object = clazz.newInstance(); } catch (Exception e) { e.printStackTrace(); } }}

还可以测试一下类加载的流程是否正确,先将Test.class文件移走,看程序是出现ClassNotFoundException异常。

 

转载于:https://www.cnblogs.com/lzeffort/p/7078389.html

你可能感兴趣的文章
酷狗的皮肤文件存放在哪
查看>>
iOS RunLoop简介
查看>>
C++的引用
查看>>
T-SQL查询进阶--深入浅出视图
查看>>
MapKeyboard 键盘按键映射 机械革命S1 Pro-02
查看>>
Android读取url图片保存及文件读取
查看>>
完整ASP.Net Excel导入
查看>>
判断CPU大小端示例代码
查看>>
ARTS打卡第13周
查看>>
循环队列的运用---求K阶斐波那契序列
查看>>
pta 编程题14 Huffman Codes
查看>>
初始化bootstrap treeview树节点
查看>>
python selenium向<sapn>标签中写入内容
查看>>
JS常用坐标
查看>>
使用”结构化的思考方式“来编码和使用”流程化的思考方式“来编码,孰优孰劣?...
查看>>
C#调用斑马打印机打印条码标签(支持COM、LPT、USB、TCP连接方式和ZPL、EPL、CPCL指令)【转】...
查看>>
关于git的认证方式
查看>>
字符串按照字典序排列
查看>>
IOS 开发调用打电话,发短信
查看>>
CI 框架中的日志处理 以及 404异常处理
查看>>