0

我使用支持实例化MyBatis的库。org.apache.ibatis.type.TypeHandler它适用于没有devtools.

但是devtools,它不起作用。

我发现当前线程中的上下文类加载器更改为org.springframework.boot.devtools.restart.classloader.RestartClassLoader.

public class Sample {

    static {
        System.out.println(Thread.currentThread().getContextClassLoader()); // RestartClassLoader
        Class<Sample> class0 = Sample.class;
        Class<Sample> class1 = (Class<Sample>) Class.forName(class0.getName());
        Class<Sample> class2 = (Class<Sample>) Class.forName(class0.getName(), false,
                ClassLoader.getSystemClassLoader());

        System.out.println(class0 == class1); // true
        System.out.println(class0 == class2); // false --- I think it is weird.
        System.out.println(class1 == class2); // false --- I think it is weird.
        
        System.out.println(class0.getClassLoader()); // RestartClassLoader
        System.out.println(class1.getClassLoader()); // RestartClassLoader
        System.out.println(class2.getClassLoader()); // sun.misc.Launcher$AppClassLoader
    }

}

类加载遵循三个简单的原则:

  1. 委托——委托原则在类尚未加载时指导我们。在这种情况下,子类加载器要求其父类加载类,直到检查引导类加载器(它确保对象层次结构 java.lang.Object 顶部的父类相同)
  2. 可见性——可见性原则确保子类加载器可以看到其父类加载的所有类。但是,反之则不然,父级看不到其子级加载的类(否则它就像一个平面类加载器,加载所有内容而没有任何隔离级别)
  3. 唯一性——唯一性原则确保一个类在类加载器层次结构的生命周期中只加载一次(由于子类对父类具有可见性,它永远不会尝试加载父类已经加载的类,但两个兄弟姐妹可能最终会在各自的类加载器中加载相同的类)

揭秘 java 类加载

我认为RestartClassLoader违反了第三个原则,对吗?

4

0 回答 0