package com.easyway.commons.ispace.dev.oop.classloaders; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; /** * 类加载机制: * 创建自定义的类加载器,只需要扩展java.lang.ClassLoader类,然后覆盖它的findClass(String name) * 方法即可。该方法根据参数指定的类的名称,返回它对应的Class对应的引用。 * 本类的:用户自定义的泪加载程序,它从path属性指定的文件目录中加载.class 文件, * 他的私有方法loadClassData(String name )能根据参数指定的类的名字,把相应的。 * class文件中二进制数据读入到内存中,并且以字节数组形式返回。 * * 由java虚拟机自带的类加载器所加载的类,在虚拟机的生命周期中,始终不会被卸载。 * java 虚拟机自带的类加载器包括根类加载器,扩展类加载器,系统类加载器。java * 虚拟机本身会始终引用这些类加载器,而这些类加载器则会始终引用它们所加载的类的Class对象。 * 由用户自定义的类加载器所加载的类是可以被卸载的。在类的加载器的内部实现中,用一个java集合来存放所加载 * 类的引用。另一方面,一个Class对象总是会引用它的类加载器。调用Class对象的getClassLoader()方法。 * 就能获取它的类加载器。一个类的实例总是引用代表这个类的Class对象。在Object类中定义了getClass()方法, * 这个方法返回代表对象所属类的Class对象的引用。此外所有的java类都有一个静态属性class,它引用代表这个类的class对象。 * @author longgangbai * @date 2010-5-8 * @version 1.0 * @since JDK6.0 */ public class CustomClassLoader extends ClassLoader{ private String name; private String path=""; private final String fileType=".class"; public CustomClassLoader(String name){ super(); this.name=name; } public CustomClassLoader(ClassLoader parent,String name){ super(parent); this.name=name; } @Override public String toString(){ return name; } /** * Loads the class with the specified <a href="#name">binary name</a>. * This method searches for classes in the same manner as the {@link * #loadClass(String, boolean)} method. It is invoked by the Java virtual * machine to resolve class references. Invoking this method is equivalent * to invoking {@link #loadClass(String, boolean) <tt>loadClass(name, * false)</tt>}. </p> * @param name * The <a href="#name">binary name</a> of the class * @return The resulting <tt>Class</tt> object * @throws ClassNotFoundException * If the class was not found */ @Override public Class<?> loadClass(String name) throws ClassNotFoundException { byte[] data=loadClassData(name); return defineClass(name,data, 0, data.length); } /** * 将类的二进制数据读入到内存中 * @param name * @return * @throws ClassNotFoundException */ @SuppressWarnings("unused") private byte[] loadClassData(String name )throws ClassNotFoundException { FileInputStream fin=null; byte[] data=null; ByteArrayOutputStream baos=null; try { name=name.replaceAll("\\.", "\\\\"); fin=new FileInputStream(new File(path+name+fileType)); baos=new ByteArrayOutputStream(); int ch=0; while((ch=fin.read())!=-1){ baos.write(ch); } data=baos.toByteArray(); } catch (Exception e) { throw new ClassNotFoundException(" class is not found : "+name,e); }finally{ try { fin.close(); baos.close(); } catch (Exception e) { e.printStackTrace(); } } return data; } public String getPath() { return path; } public void setPath(String path) { this.path = path; } /** * 在父委托机制中,各个加载器按照父子关系形成了树形结构。除了根类加载器以外其余的类加载器都有且只有一个父加载器。 * 需要指出的是: * 加载器之间的父子关系实质上指的是加载对象之间的包装关系。而不是类之间的继承关系。一对父子关系加载器可能是同 * 一个加载类的两个实例,也可能不是。在子加载器对象中包装了一个父加载器对象。 * 如load2的父加载load1 * Class sampleClass=load2.loadClass(ClassLifeLine.class.getName()); * 如下:load2首先从自己的命名空间中查找ClassLifeLine类是否被加载,如果已经加载,就直接返回代表ClassLifeLine * 类的class对象应用。如果没有加载,load1首先请求load2代为加载,load1再请求系统类加载器代为加载,系统类加载 * 器再请求扩展类加载器代为加载,扩展类加载器再请求根类加载器代为加载。若根类加载器和扩展类加载器都不能加载, * 则系统类加载器尝试加载若能加载成功,则ClassLifeLine类所对应的Class对象的引用返回给load1,load1将引用返回 * load2,从而加载ClassLifeLine到虚拟机。如果系统类加载器不能加载成功,则load1尝试加载ClassLifeLine类, * 如load1也加载不成功,则load2加载。若所有的附加载器以及load2本省不能加载,则抛出ClassNotFoundException异常。 * * 父委托机制的优点:提供了软件系统的安全性。因为在此机制下,用户自定义的类加载器不可能加载应该由父加载器加载的可靠类。 * 从而防止不可靠的甚至恶意的代码代替父加载器的可靠代码。 * * 如java.lang.Object总是由有根类加载器加载,其任何用户自定义的泪加载器都不可能加载含有恶意代码的java.lang.Object类。 * 1.命名空间:每一个类加载器都有自己的命名空间,命名空间有该类加载器及所有父加载器所加载的类组成。在同一命名空间中, * 不会出现类的完整名字(包括类的包名)相同的两个类;在不同的命名空间中,有可能会出现类的完整名字(包括类的包名)相同的类。 * * 2.运行时包: * 由同一类加载的属于相同包的类成了运行时包,决定两个类是不是属于同一个运行时包。不仅要看他们的包名是否相同。还要看 * 定义的类加载器是否相同。只有属于同一运行是宝的类次啊能互相访问包可见(默认访问的级别)的类和类成员,这样的限制能 * 避免用户自定义的类冒充核心库的类,去访问核心类库的包可见成员。 例如:用户自己定义的java.lang.Spy ,并有用户 * 自定义的类加载器加载。由于java.lang.* 和java.lang.Spy 由不同的加载器,他们属于不同的运行时包。所以java.lang.Spy * 不能访问核心类苦苦java.lang包中的包可见成员。 * @param args */ public static void main(String[] args) { CustomClassLoader load1=new CustomClassLoader(ClassLifeLine.class.getName()); load1.setPath(System.getProperty("user.dir")); CustomClassLoader load2=new CustomClassLoader(load1,ClassCircleLine.class.getName()); load2.setPath(System.getProperty("user.dir")); CustomClassLoader load3=new CustomClassLoader(null,SystemClassLoad.class.getName()); load3.setPath(System.getProperty("user.dir")); } }
相关推荐
自定义类加载器需要继承`java.lang.ClassLoader`类,并重写`findClass`方法来实现自定义加载逻辑。 自定义类加载器的基本流程包括: 1. 重写`findClass`方法,实现类的查找与加载逻辑。 2. 通过调用`super.load...
本篇文章将深入探讨Java的双亲模型类加载机制,以及如何通过自定义类加载器实现特定功能。 首先,双亲模型类加载器的工作原理是基于委托机制,即当一个类加载器收到加载类的请求时,它不会立即尝试加载,而是先委托...
深入研究Java的类加载机制 Java类加载机制是Java虚拟机的一项核心技术,可以在运行时刻动态地加载或替换系统的某些功能模块,而不影响系统其他功能模块的正常运行。类加载机制是Java虚拟机中的一项重要技术,可以使...
### Java类加载机制详解 #### 一、引言 Java 的类加载机制是 Java 运行时环境(JRE)中的一个重要组成部分。它负责将 Java 类的字节码(.class 文件)加载到 Java 虚拟机(JVM)中,并确保类的正确加载、链接和...
Java 类加载机制原理与实现 Java 类加载机制是 Java 虚拟机(JVM)的一部分,负责将编译后的 Java 字节码文件加载到 JVM 中,以便执行 Java 程序。类加载机制是 JVM 的核心组件之一,对 Java 程序的执行和安全性起...
Java 类加载机制是Java平台的核心特性之一,它负责将类的字节码加载到Java虚拟机(JVM)中并转换为运行时的类对象。理解这一机制对于优化应用程序性能和解决类相关的错误至关重要。 首先,类加载的过程分为三个主要...
自定义Java类加载器允许我们根据特定需求扩展默认的加载机制,例如,从非标准位置加载类或者实现动态加载。在Java中,类加载过程分为加载、验证、准备、解析和初始化五个阶段。 首先,让我们了解Java中的默认类加载...
Java类加载机制是Java平台核心特性之一,它负责将类的.class文件加载到JVM(Java虚拟机)中,使得程序能够运行。本篇主要基于“译 Java类加载机制(一、二)”的博客内容,深入探讨Java的类加载过程、类加载器以及...
JAVA 类加载机制是Java平台核心特性之一,它关乎到程序的运行时环境和代码的动态加载。理解这一机制有助于开发者解决与对象创建、配置问题、应用程序发布等相关的问题。以下是关于JAVA 类加载机制的详细分析: 首先...
在Java编程语言中,类加载器(ClassLoader)是运行时环境...理解类加载机制并正确实现自定义加载器是提升Java应用开发能力的重要一步。在实际项目中,合理利用类加载器可以解决很多复杂问题,比如模块化、动态更新等。
### JAVA类加载机制与动态代理 #### 一、类加载机制 ##### 1.1 类加载的时机 类加载机制负责将描述类的数据从`.class`文件加载到内存,并进行必要的校验、转换解析和初始化,使之成为可以被Java虚拟机直接使用的...
通过自定义加载器来加载加密过的 Java 类文件,可以实现快速的部署二级网站,增强网站管理平台的灵活性和可扩展性。 Java 动态类加载机制的优点包括: * 可以在运行时加载类文件,不需要重新启动应用程序 * 可以...
Java注解、反射、字节码和类加载机制是Java编程中的核心概念,它们在实际开发中扮演着重要角色。让我们深入探讨这些知识点。 **Java注解(Annotation)**: Java注解是一种元数据,它提供了在编译时或运行时处理代码的...
Java类加载机制是Java程序运行的关键部分,它使得程序能够在运行时动态加载和执行。类加载涉及多个步骤,包括加载(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)和初始化...
Java 类加载机制是Java技术体系中的重要组成部分,它关乎到程序运行时的类查找与实例化。当遇到`java.lang.ClassNotFoundException`异常时,通常是因为类加载过程出现了问题。了解类加载机制对于解决这类问题至关...
Java类加载机制是Java运行时环境中的核心组成部分,它负责将编译后的字节码(.class文件)加载到Java虚拟机(JVM)中,使得程序能够执行。这一过程涉及多个步骤,包括加载、验证、准备、解析和初始化。理解类加载...
Java动态类加载机制是Java虚拟机(JVM)运行时的一个重要特性,它允许在程序运行过程中动态地加载类文件。这种机制在不影响其他功能模块的情况下,可以动态加载必要的类,从而使得程序具备更高的灵活性和扩展性。...
在Java中,类加载器(Class Loader)是一项核心机制,用于将字节码(.class文件)加载到JVM中,使其成为运行时的对象。类加载器不仅实现了类的加载功能,还确保了Java程序在多线程环境中的安全性和隔离性。类加载器...