线程上下文类加载器与服务器类加载原理

双亲委派机制以及类加载器的问题

一般情况下.保证同一个类中所关联的其他类都是由当前类的类加载器所加载的。
比如,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);//sun.misc.Launcher$AppClassLoader@cb6009


        //获得上下文类加载器,默认也是应用类加载器
        ClassLoader loader2 = Thread.currentThread().getContextClassLoader();
        System.out.println(loader2);//sun.misc.Launcher$AppClassLoader@cb6009

        //设置为自定义的文件系统类加载器
        Thread.currentThread().setContextClassLoader(
                new FileSystemClassLoader("G:/program/java/hello/bin"));
        System.out.println(Thread.currentThread().getContextClassLoader());//JVMProcess.FileSystemClassLoader@3e0ebb



        try {
            Class<Demo> c = (Class<Demo>)Thread.currentThread().getContextClassLoader().loadClass("JVMProcess.Demo");
            System.out.println(c);
            System.out.println(c.getClassLoader());//sun.misc.Launcher$AppClassLoader@cb6009


            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需要实现自己的类加载器。–我可以限制你只能把类写在指定的地方,否则我不给你加载。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

吃果冻不吐果冻皮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值