JVM

JVM类加载机制

2019-02-12  本文已影响8人  黄靠谱

概述

class物理文件加载到JVM内存中,可以有多种加载方式:

类的加载器和核心类

  1. 核心类加载器
  1. 加载的特点
  1. 加载的结果
  1. 核心方法: loadClass、 findLoadedClass、parent.loadClass、findBootStrapClass、findClass

自定义类加载器

实现自定义class文件加载路径,实现,class文件包路径的限制

https://www.cnblogs.com/gdpuzxs/p/7044963.html

实现逻辑:写一个classloader类(构造函数里面需要传入包真实的路径),重写findClass方法,

public class MyClassLoader extends ClassLoader{
    public MyClassLoader(String classpath) {
        this.classpath = classpath;
    }

    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        try {
            byte [] classDate=getDate(name);
            
            if(classDate==null){}
            
            else{
                return defineClass(name,classDate,0,classDate.length);
            }
            
        } catch (IOException e) {
            
            e.printStackTrace();
        }
        
        return super.findClass(name);
    }
}

实现类的每次重新加载,实现热加载

  1. 本来重写 findLoadedClass()即可,直接返回null,实现热加载,但是ClassLoader把该方法设置为final了,不希望去破坏这个规则
  2. 所以直接通过重写过的findClass来实现,相当于在上面的基础上做修改,findClass的路径为当前路径,每次loadClass,直接调用findClass方法即可,虽然只能修改本地的class类
  3. findClass需要defineClass来最终把字节码文件加载进内存当中,JVM默认相同的类加载器不能加载相同全路径的类,所以每次重新加载的时候需要new一个自定义加载器,否则会报错
    String currentPath=Class.class.getClass().getResource("/").getPath()

    MyClassLoader myClassLoader=new MyClassLoader(currentPath);
    Class c=myClassLoader.findClass("com.test.Action.Test");
    
    MyClassLoader myClassLoader2=new MyClassLoader(currentPath);
    Class c2=myClassLoader2.findClass("com.test.Action.Test");

tomcat的类加载模型

  1. 核心加载器
  1. 层级结构
  1. 加载逻辑(源码 org.apache.catalina.loader.WebappClassLoader#loadClass)
    tomcat的类加载机制是违反了双亲委托原则的:先本地缓存查找,再全局缓存查找,再系统加载,再自己加载,最后再父加载器加载

反射和Spring IOC

上一篇下一篇

猜你喜欢

热点阅读