사용자 정의 클래스 로더를 사용하여 클래스 파일을로드하려면 java.lang.classloader 클래스를 상속해야합니다.
클래스 로더에는 몇 가지 중요한 방법이 있습니다.
ProtectedClassLoader (ClassLoaderParent) : 대의원 작업을 위해 지정된 부모 클래스 로더를 사용하여 새 클래스 로더를 만듭니다.
ProtectedFinalClass <?> defineClass (StringName, byte [] b, intoff, intlen) : 바이트 배열을 클래스 클래스의 인스턴스로 변환합니다.
ProtectedClass <?> findclass (StringName) : 지정된 이진 이름으로 클래스를 찾으십시오.
publicclass <?> loadclass (StringName) : 지정된 이진 이름으로 클래스를로드하십시오.
ProtectedFinalClass <?> findloadedClass (StringName) : Java 가상 머신 이이 로더를 주어진 바이너리 이름을 가진 클래스의 시작 로더로 기록한 경우 해당 바이너리 이름을 가진 클래스가 반환됩니다. 그렇지 않으면 NULL을 반환하십시오.
PublicFinalClassLoaderGetParent () : 위임 된 상위 클래스 로더를 반환합니다.
ProtectedFinalVoidresolveClass (클래스 <?> C) : 지정된 클래스에 링크.
상위 대의원 모델을 따르려면 FindClass (StringName) 메소드를 다시 작성하십시오. 상위 대의원 모델을 따르지 않으려면 LoadClass (StringName) 메소드를 직접 다시 작성하십시오.
상위 대의원 모델을 따르는 클래스 로더를 사용자 정의하십시오
ParentsDelegateClassloader.java
package com.zzj.classloader; import java.io.bytearrayoutputStream; import java.io.file; import java.io.fileInputStream; import java.io.ioexception; import java.io.inputStream;/** * 학부모의 대가 로드러 및 우선 Class */Public Class */Authorator */Public Classe */public classe */** */** */** * ** */** */** */** */public Class */Public Classe */** ParentsDelegateClassLoader 확장 클래스 로더 {private static final string ext = ".class"; private String path; public parents this.getResource ( ""). getPath ();} public arpersdelegateclassloader (string path) {this.path;}@Injectrected Class <? findclass (findclass) classNotFoundException {byte [] b = null; try {b = loadclassfile (name);} catch (ioexception e) {e.printstacktrace ();} return this.defineClass (name, b, 0, b.length);} loadclassfile (문자열 이름) trows ioexcmeption = getClassFile (name); system.out.println ( "클래스 파일이 곧로드 될 것입니다" + classFile); bytearRayoutputStream out = new ByTearRayoutputStream (); inputStream input = new FileInputStream (classFile); int count [] temp = new Byte [1024]); {out.write (temp, 0, count);} out.close (); input.close (); return out.tobytearRay ();} private string getClassFile (String Name) {String PathName = name.replace ( ".", file.separator); if (path.endswith ( "/"))) {// ")) ext;} return path + file.separator + pathname + ext;}}}이제 classpath classpath에 클래스 파일 com/zzj/classloader/user.class가 있으며 f : // classloaderTest // bin 디렉토리가 있습니다. 패키지 이름은 com.zzj.classloader입니다. 클래스 로더 ParentselegateClassLoader를 사용하여 f : // classloaderTest // bin 아래에 클래스를로드하십시오.
package com.zzj.classloader; public class app {private static final string path = "f : // classloadertest // bin"; private static final string classname = "com.zzj.classloader.user"; public static void main (strings) throws {ParentsDelegeTeclassLoader = classoclass hoptler (PARTIATECLASS); classload.loadclass (classname); system.out.println (clazz); system.out.println (clazz.getclassloader ());}}산출:
클래스 com.zzj.classloader.user sun.misc.launcher$appclassloader@19821f
사용자 클래스의 로더는 시스템 클래스 로더 AppClassLoader입니다. 우리가 스스로 정의하는 클래스 로더가 아닙니다. 실제로, 그것은 f : // classloadertest // bin에 따른 클래스가 아니라 클래스 경로 아래의 클래스입니다. 이것은 학부모 대의원 모델입니다. ParentsDelegateClassLoader 로더가로드 요청을 받으면 먼저 상위 클래스 로더에 위임됩니다. 상위 클래스 로더가 성공적으로로드되면 클래스 객체가 반환됩니다. 로드가 실패하면 부하 요청을받은 클래스 로더가로드됩니다.
ClassPath에서 사용자 클래스를 테스트 실행으로 삭제하십시오.
클래스 파일은 곧로드 될 것입니다.
현재 사용자 클래스는 ParentsLegateClassLoader로로드됩니다.
클래스 로더의 소스 코드에서 확인할 수 있습니다.
public class <?> loadclass (문자열 이름)는 classNotFoundException {return loadclass (이름, false)를 던집니다. }과부하 된 방법을 다음과 같이 호출했습니다.
보호 된 동기화 된 클래스 <?> loadclass (문자열 이름, 부울 resolve)는 classNotFoundException {// 먼저 클래스가 현재 클래스 로더 클래스에 의해로드되었는지 여부를 결정합니다. c = findloadedClass (name); if (c == null) {try {if (parent! = null) {// 부모 클래스 로더가 존재하면 부모 클래스에 위임하여 c = parent.loadclass (이름, false); } else {// 상위 클래스가 비어 있으면 부모 클래스 로더가 부팅 클래스 로더 C = FindBootStrapClass0 (이름); }} catch (classNotFoundException e) {// 상위 클래스 로더가로드되지 않으면 자체로드하고 FindClass 메소드를 호출합니다! c = findClass (이름); }} if (resolve) {resolveClass (c); } 반환 c; }상위 대표 모델을 파괴하려면 loadclass (StringName) 메소드를 직접 다시 작성할 수 있음을 알 수 있습니다.
부모 위임 모델을 따르지 않는 클래스 로더 사용자 정의
NOTPARENTSDELEGATECLASSLOADER.JAVA
package com.zzj.classloader; import java.io.bytearrayoutputStream; import java.io.file; import java.io.fileInputStream; import java.io.filenotfoundException; import java.io.io.ioexception; import java.io.inputstream;/**의로드*) @Author Administrator */public class notparentsDelegateClassLassler는 클래스 로더를 확장합니다 {private static final string ext = ".class"; private String Path; public notparentSdelegateClassLoader () {path = this.getResource ( "). getPath ();} public notparentSdelegeTeclasslass (threat path) {this. class <?> loadclass (문자열 이름)는 classNotFoundException {byte [] b = null; try {b = loadClassFile (name);} catch (fileNotFoundException e) {System.err.println ( "loader" + this.getname () + "found" + ", delegate to delegated"); 부모 클래스 로더 리턴 getClass (). getClassLoader (). loadClass (name);} catch (ioException e) {system.err.println ( "loader" + this.getClass (). getName () + " + 이름 +"실패, 부모 클래스로드에 위임된다! "; getClass (). getClassLoader (). loadClass (이름);} // 클래스가 현재 클래스 로더가로드했는지 여부를 확인하십시오 (부모 클래스 로더가 아닌 현재 클래스 로더 만 확인) 클래스 <?> clazz = findloadedClass (name); if (Clazz! = null) {system.out.println ( "class" + "retoy!"); {system.out.println ( "class" + name + "아직로드되지 않음!");} retract this.defineClass (name, b, 0, b.length);} private byte [] loadclassfile (String Name) IoException, filenotfoundException {string classfile = get classfile (name); classFile); bytearRayoutputStream out = new ByTearRayoutputStream (); inputStream input = new FileInputStream (classFile); int count; byte [] temp = new Byte [1024]; while (count = input.read (temp))) {out.write (temp, 0, 0, count);} out.close (); input.close (); return out.tobytearRay ();} private String getClassFile (string name) {String PathName = name.replace ( "." pathname + ext;}}이제 ClassPath ClassPath 아래에 클래스 파일 com/zzj/classloader/user.class가 있으며 패키지 이름 com.zzj.classloader가있는 사용자 클래스는 로더 notparentsDelegateClassLasser입니다.
package com.zzj.classloader; public class app2 {private static final string classname = "com.zzj.classloader.user"; public static void main (String [] args)은 예외 {notparentsDelegateClassLoader ClassLoader = new notparentsDelegateClassLassLoader (); clazz => Clazz = classload.loadclass (classname); system.out.println (clazz); system.out.println (clazz.getclassloader ());}}산출:
클래스 파일 /e:/myeclipse/zzjtest/webroot/web-inf/classes/com/zzj/classloader/user.class class com.zzj.classloader.user는 아직로드되지 않았습니다! 클래스 파일은 곧로드 될 것입니다/e :/myeclipse/zzjjjtest/webroot/web-inf/classes/java/lang/object.class class com.zzj.classloader.user com.zzj.zzj.zzj.classloader.notparentsdelegateclassloader@61de33 Comc.zclass.notparentsdelegateclasler.notparentsdelegateclasse java.lang.object는 찾을 수 없으며 부모 클래스 로더에 위임됩니다!
현재 사용자 클래스의 로더는 NotParentsDelegateClassLoader이며, 먼저 부모 클래스에 위임되지 않았습니다. 부하가 실패한 경우 부모 클래스 로더에만 위임됩니다. 이것은 부모 대의원 모델과 반대입니다.
물론, 부하가 실패하더라도 부모 클래스 로더로 위임하지 않고 지정할 수 있으므로보다 복잡한 메쉬 모델의 클래스로드 메커니즘을 구축 할 수 있습니다.
요약
위의 내용은 Java Custom Class 로더의 코드 예제에 관한 것입니다. 모든 사람에게 도움이되기를 바랍니다. 관심있는 친구는이 사이트의 다른 관련 주제를 계속 참조 할 수 있습니다. 단점이 있으면 메시지를 남겨 두십시오. 이 사이트를 지원해 주신 친구들에게 감사드립니다!