`
zy19982004
  • 浏览: 661796 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
博客专栏
F6f66edc-1c1a-3859-b76b-a22e740b7aa7
Hadoop学习
浏览量:251950
社区版块
存档分类
最新评论

Java ClassLoader学习四:ContextClassLoader

 
阅读更多

 

一.ContextClassLoader

  1. ContextClassLoader只是一个逻辑上的概念,在Java Api里并没有一个叫ContextClassLoader的类。
  2. JVM默认类加载体系已经能满足大部分情况的使用了,那为什么还需要ContextClassLoader呢。但有时候这样的加载体系并不能满足要求,比喻需要动态加载应用程序开发人员提供的资源时。考虑JDBC的实现,JDK中的JDBC Api是由BootStrap加载的,当我们确定使用某一厂商的JDBC实现时,实现类也会由BootstrapLoader加载,显然BootstrapLoader是加载不了的。于是就出现了ContextClassLoader这个概念。JDBC Api里使用ContextClassLoader去加载实现类,默认情况ContextClassLoader就是AppClassLoader(参考http://zy19982004.iteye.com/blog/1983236),刚好可以加载位于classpath下的实现类。
  3. 再说的清楚一点,ContextClassLoader就是Thread的一个属性,提供了get和set方法,因此任何地方都可以设置并获得这个ClassLoader。
    private ClassLoader contextClassLoader;
  4. 在没有显示setContextClassLoader的时候,getContextClassLoader默认返回的是该线程的父线程的ClassLoader。
    public void setContextClassLoader(ClassLoader cl){}
    public ClassLoader getContextClassLoader() {}
  5. 其实还有一个办法,把AppClassLoader保存起来,当BootstrapLoader加载不到实现类时,用AppClassLoader去加载。

二.学习例子

package com.jyz.study.jdk.classLoader;

import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;

/**
 *  演示ContextClassLoader的使用
 *  @author JoyoungZhang@gmail.com
 *  
 */
public class ContextClassLoaderTest {
    
	public static void main(String[] args) throws MalformedURLException, ClassNotFoundException {
		System.out.println("MainClass getClassLoader: " + ContextClassLoaderTest.class.getClassLoader());
		System.out.println("MainClass getContextClassLoader: " + Thread.currentThread().getContextClassLoader());
		Thread innerThread1 = new InnerThread1();
		innerThread1.start();
	}
	
}

class InnerThread1 extends Thread{
	@Override
	public void run() {
		try {
			URL[] urls = new URL[1];
			urls[0] = new URL("jar:file:/E:/GoogleCode/platform-components/trunk/SourceCode/component-core/target/component-core-1.0.jar!/");
			URLClassLoader urlClassLoader = new URLClassLoader(urls);
			Class<?> clazz = urlClassLoader.loadClass("com.jyz.component.core.collection.Tuple");
			System.out.println(clazz.newInstance());
			
			System.out.println("InnerThread1 getClassLoader: " + clazz.getClassLoader());
			System.out.println("InnerThread1 getContextClassLoader: " + Thread.currentThread().getContextClassLoader());
			
			this.setContextClassLoader(urlClassLoader);
			
			Thread innerThread2 = new InnerThread2();
			innerThread2.start();
		}catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
	}
}


class InnerThread2 extends Thread{
	@Override
	public void run() {
		try {
			ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
			classLoader.loadClass("com.jyz.component.core.collection.Triple");
			System.out.println("InnerThread2 getContextClassLoader: " + Thread.currentThread().getContextClassLoader());
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}
}


console output:
MainClass getClassLoader: sun.misc.Launcher$AppClassLoader@f6a746
MainClass getContextClassLoader: sun.misc.Launcher$AppClassLoader@f6a746
Tuple[t1:null, t2:null]
InnerThread1 getClassLoader: java.net.URLClassLoader@f9f9d8
InnerThread1 getContextClassLoader: sun.misc.Launcher$AppClassLoader@f6a746
InnerThread2 getContextClassLoader: java.net.URLClassLoader@f9f9d8


注释掉36行时console output:
MainClass getClassLoader: sun.misc.Launcher$AppClassLoader@f6a746
MainClass getContextClassLoader: sun.misc.Launcher$AppClassLoader@f6a746
Tuple[t1:null, t2:null]
InnerThread1 getClassLoader: java.net.URLClassLoader@f9f9d8
InnerThread1 getContextClassLoader: sun.misc.Launcher$AppClassLoader@f6a746
java.lang.ClassNotFoundException: com.jyz.component.core.collection.Triple
...异常栈信息

 

1
0
分享到:
评论

相关推荐

    classloader-playground, 一个简单的java依赖隔离容器类.zip

    开源项目"classloader-playground"为我们提供了一个学习和实验Java类加载器的绝佳平台。 首先,我们来理解一下什么是类加载器。在Java中,类加载的过程包括加载、验证、准备、解析和初始化五个阶段。类加载器主要...

    Tomcat研究之ClassLoader.pdf

    2. **System ClassLoader**:通常由JVM的`java.class.path`系统属性指向,负责加载`$CATALINA_HOME/bin/bootstrap.jar`中的类库,这些类主要用于初始化Tomcat并执行主方法。 3. **Common ClassLoader**:这个类加载...

    在Java的反射中,Class.forName和Class

    JVM内置了三个默认的ClassLoader: 1. **Bootstrap ClassLoader**:加载JDK自身的类,如rt.jar中的类。 2. **Extension ClassLoader**:加载JRE扩展目录下的jar文件。 3. **App ClassLoader**:也称为系统类加载器...

    classloader

    1. Bootstrap ClassLoader:这是最基础的类加载器,负责加载系统的预定义类,如java.*和android.*包下的类。它是由C++实现的,并且是不可见的,开发者通常不直接与之交互。 2. Extension ClassLoader:扩展类加载器...

    ClassLoader类加载机制和原理详解

    当一个类被加载时,它首先会尝试由当前线程的Context ClassLoader进行加载,如果该类加载器无法加载,则向上委托给父类加载器,直至Bootstrap ClassLoader。这种设计可以避免类的重复加载,同时保证核心库的稳定性和...

    浅析ClassLoader

    三、上下文类加载器(ContextClassLoader) 1. 定义:在多线程环境中,每个线程都有一个与之关联的ClassLoader,称为上下文类加载器。通常,线程的上下文类加载器由创建该线程的代码设置,用于加载线程中使用的特定...

    jboss 5 原理 2 classloader

    1. `classloader`:包含了自定义的`java.lang.ClassLoader`扩展,但没有特定的类加载策略。这个子项目主要关注类加载的基础功能,即从何处加载类以及如何加载。 2. `classloading`:这是Microcontainer依赖注入机制...

    reload-java:在Java 8中尝试使用ClassLoader

    重新载入Java 支持类重载的ClassLoader的简单实现运行示例构建项目开始示例 gradle buildjava -cp build/classes/test/:build/libs/reload-java-1.0.jar reload.ReloadExample1该应用程序将等待输入,输入r + 已加载...

    Java或web中解决所有路径问题

    在Java Web开发中,路径问题往往困扰着许多开发者,尤其是在处理资源定位、文件读取以及配置文件加载等场景时。本文将深入解析Java Web中所有路径问题的解决方法,涵盖Servlet、Action、Controller、Filter、...

    Tomcat.ClassLoader.rar_Java编程_Java_

    可能还会讨论到线程上下文类加载器(Thread Context ClassLoader)和自定义类加载器的编写,这些都是Java企业级开发中的高级话题。 理解并掌握Tomcat的类加载机制对于开发者来说是必要的,特别是当面临性能优化、类...

    java面试题(整理)

    这个问题旨在了解求职者对于Java学习的态度和深度。常见的Java学习书籍包括但不限于: - 《Java核心技术》 - 《Effective Java》 - 《Thinking in Java》 - 《Java编程思想》 - 《Java并发编程实战》 2. **...

    java动态特性eval

    通过这个接口,我们可以先将字符串转换为Java源代码,然后编译成字节码,最后通过`ClassLoader`加载并执行。这种方式可以实现动态编译和执行Java代码,但它需要处理语法解析、异常处理和类型检查等复杂问题。 4. **...

    Java类加载原理解析

    除了这三种预定义的类加载器,Java还提供了一种特殊的**线程上下文类加载器(Thread Context ClassLoader)**,它允许在特定线程中加载类时使用非默认的类加载器。这在插件框架和OSGi等动态部署环境中尤其有用。 ...

    java操作properties方法

    1. 使用当前线程的`ContextClassLoader`:`Thread.currentThread().getContextClassLoader().getResourceAsStream("filename")` 2. 使用类的`ClassLoader`:`this.getClass().getClassLoader().getResourceAsStream...

    安卓原生热更新 classloader

    `ClassLoader`是Java和安卓系统中的一个重要组件,它的主要职责是加载类到Java虚拟机(JVM)或者 Dalvik 虚拟机(DVM)中。在安卓环境下,`ClassLoader`负责解析应用的`.apk`文件,提取`.dex`文件,并将其转换为可...

    java面试八股文.pdf

    - **简单性**:Java语言设计简洁明了,易于学习。 - **面向对象**:支持类、对象、继承、多态等面向对象编程特性。 - **健壮性**:拥有强大的错误检查机制和垃圾回收机制,减少了程序出错的可能性。 - **安全性*...

    java class reload

    1. **Java ClassLoader原理** - Java程序在运行时,类的加载是由ClassLoader负责的。默认情况下,当类被加载后,除非应用停止,否则ClassLoader不会重新加载该类。 - Java的双亲委托模型(Parent Delegation Model...

    深入探讨 Java 类加载器

    线程上下文类加载器(Thread Context ClassLoader)是一个特殊的角色,它允许在多线程环境中控制类的加载。每个线程都有一个与之关联的类加载器,可以通过Thread.currentThread().getContextClassLoader()获取。这在...

    Java类加载机制学习1

    线程上下文类加载器(Thread Context ClassLoader)是Java提供的一种机制,允许线程在运行时指定一个类加载器,确保类由同一个类加载器加载。这对于应用程序服务器和插件系统尤其有用,因为它允许组件使用自己的类...

Global site tag (gtag.js) - Google Analytics