`

SpringDM笔记14-The thread context classloader 及在OSGi中的运用

 
阅读更多

1. Using the thread context classloader(TCCL)

    By default, the TCCL is the application’s classloader, it can be accessed through the

    getContextClassLoader method of the current thread, as shown in the following snippet:
    ClassLoader currentTccl = Thread.currentThread().getContextClassLoader();

   
    To specify a different classloader, use the setContextClassLoader method of the current thread, as

    shown in this snippet:
    Thread.currentThread().setContextClassLoader(TcclActivator.class.getClassLoader());

2. Using the thread context classloader with OSGi

    益处:Using the TCCL within OSGi makes it possible to solve some problems without having to

    export  and import packages. In particular, it helps frameworks that don’t know until runtime

    which classes  they need to use.

 

    ClassNotFoundExceptions :以Hibernate引擎加载映射的类为例:

    Hibernate is a generic ORM framework without dependencies on user applications(如映射的类). By
    default, implementation bundles for these kinds of frameworks don’t import application classes.

    Hibernate can’t load the mapped classes because they’re user-defined classes and aren’t 

    specified in the Import-Package header of the Hibernate component. The framework tries to

    discover the required classes through configuration will be throw ClassNotFoundExceptions。

    解决这个问题需要用到TCCL,因为大部分的框架(如:Hibernate)可以在多个ClassLoader中查找需要的类,If 

    the caller’s bundle has set the context classloader with its associated classloader, the framework

    bundle will be capable of instantiating classes that are visible only to the caller’s bundle.

 

    例如下面资源文件bundle-context.xml中配置了一个bean,这个bean对当前的Bundle是可见的,当加载资源文

    件时将会抛出ClassNotFoundException:
    FileSystemXmlApplicationContext context = null;
    try {
           context = new FileSystemXmlApplicationContext("resources/bundle-context.xml");
    } finally {
           if (context!=null) {
               context.close();
           }
    }

    解决方法:Using the context classloader when creating a Spring container:

    ClassLoader currentTccl = Thread.currentThread().getContextClassLoader();
    Thread.currentThread().setContextClassLoader(TcclActivator.class.getClassLoader());
         FileSystemXmlApplicationContext context = null;
         try {
               context = new FileSystemXmlApplicationContext("resources/bundle-context.xml");
         } finally {
               if (context!=null) {
                     context.close();
               }
              Thread.currentThread().setContextClassLoader(currentTccl);
    }

 

 

 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics