深入类加载器----线程上下文类加载器

来源:互联网 发布:我与网络强国演讲稿 编辑:程序博客网 时间:2024/05/16 09:18

            深入类加载器(四)----线程上下文切换类加载器

                      线程上下文类加载器


 

我们知道在java中的加载器的加载模式是双亲委托模式,这种模式是遵从父类优先的原则。

但是在一些场合中,这种双亲委托机制反而是行不通的。

最典型的是JDBCApi:其实JDBCApi包括俩部分:一部分是oragle公司提供的接口类,一部分是具体的厂商提供的实现类,也就是所谓的driver驱动部分。比如是要使用mysql数据库的话,那么就需要加载mysql数据库的驱动。如果还是按照,双亲委托机制的话,那么对于oragle公司提供的接口部分就是由拓展类加载器来进行进行加载的。注意,接口也是一种类型,也需要被类加载器进行加载才可以。

我们要明白一点,一般来说,接口和具体的实现应该由同一个的类加载器进行加载。如果是由不同的加载器进行加载的话,那么就会造成接口找不到具体的实现。这是不行的。

但是至于厂商提供的具体的实现的部分,也就是第三方的jar包,一般是由应用程序类加载器进行加载的。这样的话,就会使接口和实现的类加载器是不一样的。这样是不行的。为了解决这个问题,就抛弃了双亲委托机制,而提出了线程上下文类加载器。在api+spi的模块框架下,很多的底层的实现都是使用了线程上下文类加载器。这是要注意的。在线程上下文类加载器中,

我们可以自定义类加载器,并且指定这种类加载器不适用双亲委托机制,这样的话,就可以使接口和具体的实现的加载器是一样的。。

从而就解决了这个问题。

下面看一个例子:

package com.lg.test;

/*这就是线程上下文切换类加载器这主要是为了防止Api+spi的错误而特定使用的*/

/*比如说,JDBC中,接口API是由oragle公司提供的,这些接口API一般是由Boot类加载器进行加载的*/

/*但是具体的实现是由App进行加载的。这样的话,就会使接口找不到实现。就会出现错误。所以我们要

 * 使用线程上下文切换来进行,使加载的类加载器都是相同的。这是要注意的*/

public class ThreadClassLoader {

    public static void main(String[] args) {

        ClassLoader loader=ThreadClassLoader.class.getClassLoader();

        System.out.println(loader);

 

        ClassLoader loader1 = Thread.currentThread().getContextClassLoader();

        System.out.println(loader1);

 

        Thread.currentThread().setContextClassLoader(new FileClassLoader("c://myjava"));

        System.out.println(Thread.currentThread().getContextClassLoader());

 

 

        try {

     Class<?>  c= Thread.currentThread().getContextClassLoader().loadClass("com.lg.test.Demo02");

            System.out.println(c);

            System.out.println(c.getClassLoader());

            

        } catch (ClassNotFoundException e) {

            e.printStackTrace();

        }

    }

}

 

 

最后的输出的结果是:

sun.misc.Launcher$AppClassLoader@4e0e2f2a

sun.misc.Launcher$AppClassLoader@4e0e2f2a

com.lg.test.FileClassLoader@15db9742

class com.lg.test.Demo02

sun.misc.Launcher$AppClassLoader@4e0e2f2a

 

为什么最后输出的还是应用程序的类加载器呢?因为这个自定义的类加载器内部还是使用了双亲委托机制,

但是我们也可以自己通过代码来控制它不是双亲委托机制的。这部分可以根据具体的需要来进行实现。

0 0
原创粉丝点击