双亲委派机制以及类加载器的问题
一般情况下.保证同一个类中所关联的其他类都是由当前类的类加载器所加载的。
比如,class A本身在Ext下找到.那么他里面new出来的一些类也就只能用Ext去查找了(不会低一个级别)。所以有些明明App可以找到的,却找不到了。
JDBC API他有实现的driver部分(mysql,sql server)。我们的JDBC APl都是由Boot或者Ext来载入的。但是JDBC driver却是由Ext或者App来载入,那么就有可能找不到driver了。在Java领城中,其实只要分成这种Api+SPI(Service Provide Interface,特定厂商提供的),就会遇到此问题。
常见的SPI有JDBC、JCE、JNDI、JAXP和JBI等。这些SPI的接口由Java核心库来提供,如JAXP的SPI接口定义包含在javax.xml.parsers包中。SPI的接口是Java核心库的一部分,是由引导类加载器来加载的SPI实现的*Java类一般是由系统类加载器来加载的。引导类加载器是无法找到SPI的实现类的,因为它只加载Java的核心库。*
通常当你需要动态加载资源的时候,你至少有三个ClassLoader可以选择:
1.系统类加载器或叫作应用类加载器system classloader,or application classloader。
2.当前类加载器
3.当前线程类加载器
线程上下文类加载器
线程类加载器是为了抛弃双亲委派加载链模式。
每个线程都有一个关联的上下文类载器。如果你使用new Thread()方式生成新的线程,新线程将继承其父线程的上下文类加载器。如果程序对线程上下文类加载器没有任何改动的话,程序中所有的线程将都使用系统类加载器作为上下文类加载器。
Thread.currentThread().getContextClassLoader()
Thread.currentThread().setContextClassLoader()
Demo:
package JVMProcess;
/**
* 线程上下文类加载机制
* @author liguodong
*/
public class ThreadClassLoader {
public static void main(String[] args) {
ClassLoader loader = ThreadClassLoader.class.getClassLoader();
//系统默认是应用类加载器
System.out.println(loader);//[email protected]
//获得上下文类加载器,默认也是应用类加载器
ClassLoader loader2 = Thread.currentThread().getContextClassLoader();
System.out.println(loader2);//[email protected]
//设置为自定义的文件系统类加载器
Thread.currentThread().setContextClassLoader(
new FileSystemClassLoader("G:/program/java/hello/bin"));
System.out.println(Thread.currentThread().getContextClassLoader());//[email protected]
try {
Class<Demo> c = (Class<Demo>)Thread.currentThread().getContextClassLoader().loadClass("JVMProcess.Demo");
System.out.println(c);
System.out.println(c.getClassLoader());//[email protected]
Class<?> c2 = (Class<?>)Thread.currentThread().getContextClassLoader().loadClass("hello.HelloWorld");
System.out.println(c2);
System.out.println(c2.getClassLoader());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
运行结果:
sun.misc.Launcher$AppClassLoader@cb6009
sun.misc.Launcher$AppClassLoader@cb6009
JVMProcess.FileSystemClassLoader@da4b71
class JVMProcess.Demo
sun.misc.Launcher$AppClassLoader@cb6009
class hello.HelloWorld
JVMProcess.FileSystemClassLoader@da4b71
注:
关于自定义的FileSystemClassLoader类,请查找
http://blog.csdn.net/scgaliguodong123_/article/details/46914759
自定义类加载器。
服务器类加载原理
Tomcat服务器的类加载机制–一切都是为了安全!
TOMCAT不能使用系统默认的类加载。
如果tomcat运行你的web项目使用类加载器(双亲委派机制)的话是相当危险的,你可以肆无忌惮的操作系统的各个目录。
对于运行在JavaEE容器中的Web应用来说,类加载器的实现方式与一般的Java应用有所不同。
每个Web应用都有一个对应的类加载器实例。该类加载器也使用化理模式(不同于前面说的双亲委托机制),所不同的是它是首先尝试去加载某个类,如果找不到再代理给父类加载器。这与一般类加载器的顺序是相反的。
为了保证安全,这样核心库就不在查询范围之内。
为了安全丁0MCAT需要实现自己的类加载器。–我可以限制你只能把类写在指定的地方,否则我不给你加载。
版权声明:本文为博主原创文章,未经博主允许不得转载。