我们知道官方版本的JVM实现,采用的是双亲加载机制,当需要加载一个类的时候,首先通过自定义的Classloader中查找是否已经加载了,若是没有找到再是SystemClassloader,再就是ExtClassLoader,最后实到BootstrapClassloader中查找,若是都没有,那么按照这个顺序再去尝试加载这个类,直到加载成功。
对于些类,我们可能并不是在系统启动时候就加载了,那么就需要自己手工去加载需要的类,基本方式有三种:
- 第一常见的加载方式new一个对象,这种方式基本走的就是双亲加载了,
- 第二种方式就是直接找到需要的Classloader来加载。
- 最后种是在已经加载过的线程上下文中取加载对象,
那么这三种加载方式还如何处理,怎么才是加载类的最佳实践呢,看看struts2中是如何实现的吧,其实很多开源框架中都存在类似的代码,例如spring。
- 首先从线程上下加载,不走双亲加载机制
- 当前的classloader中加载
- 走双亲加载机制
- 通过外部调用类的JVM进行加载
public static Class loadClass(String className, Class callingClass) throws ClassNotFoundException {
try {
return Thread.currentThread().getContextClassLoader().loadClass(className);
} catch (ClassNotFoundException e) {
try {
return Class.forName(className);
} catch (ClassNotFoundException ex) {
try {
return ClassLoaderUtils.class.getClassLoader().loadClass(className);
} catch (ClassNotFoundException exc) {
return callingClass.getClassLoader().loadClass(className);
}
}
}
}
0 条评论。