자바 류 캐리어 계층 구조 원리 분석
유도 클래스 로 더(boottstrap class loader)
자바 의 핵심 라 이브 러 리 불 러 오기(JAVAHOME/jre/lib/rt.jar 또는 sun.boot.class.path 경로 의 내용)은 네 이 티 브 코드 로 이 루어 집 니 다(C 로 이 루어 집 니 다).자바.lang.classLoader 에서 계승 되 지 않 습 니 다.
확장 클래스 와 응용 프로그램 클래스 로 더 를 불 러 오고 부모 클래스 로 더 를 지정 합 니 다.
확장 클래스 로 더(extensions class loader)
자바 의 확장 라 이브 러 리 불 러 오기(JAVAHOME/jre/lib/ext/*.jar 또는 java.ext.dirs 경로 의 내용)자바 가상 컴퓨터 의 구현 은 확장 라 이브 러 리 디 렉 터 리 를 제공 합 니 다.이 종류의 로 더 는 이 디 렉 터 리 에서 자바 류 를 찾 아 불 러 옵 니 다.
sun.miscLauncher$ExtClassLoader 가 있 습 니 다.자바.lang.ClassLoader 에서 계승 합 니 다.
응용 프로그램 클래스 로 더(application class loader)
자바 응용 클래스 경로(classpath,java.classs.path 경로)에 따라 지정 한 경로 의 클래스 를 불 러 옵 니 다.일반적으로 자바 응용 클래스 는 불 러 옵 니 다.
sun.misc.Launcher$AppClassLoader 에서 이 루어 집 니 다.java.lang.ClassLoader 에서 계승 합 니 다.
사용자 정의 클래스 로 더
개발 자 는 자바.lang.ClassLoader 류 를 계승 하 는 방식 으로 자신의 클래스 로 더 를 실현 하여 특수 한 수 요 를 만족 시 킬 수 있다.
설명:자바 에서 클래스 의 로 딩 은 부모 위탁 체 제 를 사용 하기 때문에 위의 몇 가지 로 딩 기 는 부자 관계 이 고 그 중에서 유도 류 로 딩 기 를 바탕 으로 합 니 다.
ClassLoader 클래스 소개
역할:
java.lang.ClassLoader 류 의 기본 적 인 직책 은 지정 한 클래스 의 이름 에 따라 해당 하 는 바이트 코드 를 찾 거나 생 성 한 다음 에 이 바이트 코드 에서 자바 류,즉 자바.lang.Class 류 의 인 스 턴 스 를 정의 하 는 것 입 니 다.
이 밖 에 도 ClassLoader 는 자바 응용 에 필요 한 자원 파일,예 를 들 어 이미지 파일 과 프로필 등 을 불 러 옵 니 다.
관련 방법:
public class Demo02 {
public static void main(String[] args) {
System.out.println(ClassLoader.getSystemClassLoader());
System.out.println(ClassLoader.getSystemClassLoader().getParent());;
System.out.println(ClassLoader.getSystemClassLoader().getParent().getParent());;
}
}
출력:sun.misc.Launcher$AppClassLoader@1016632
sun.misc.Launcher$ExtClassLoader@dc6a77
null
순서대로 로 더,확장 로 더,가이드 로 더 를 사용 합 니 다.
클래스 로 더 의 프 록 시 모드:
프 록 시 모드:지정 한 종 류 를 불 러 오 는 다른 로 더 에 게 건 네 줍 니 다.
양친 위탁 메커니즘:
특정한 클래스 로 더 는 로 더 류 의 요청 을 받 았 을 때 먼저 로 더 임 무 를 아버지 클래스 로 더 에 의뢰 하여 가장 높 은 할아버지 세대 까지 거 슬러 올 라 가 는 것 이다.만약 에 아버지 클래스 로 더 가 클래스 로 더 임 무 를 완성 할 수 있다 면 성공 적 으로 돌아 갈 수 있다.부모 클래스 로 더 가 이 로 딩 작업 을 수행 할 수 없 을 때 만 스스로 불 러 옵 니 다.
부모 의뢰 체 제 는 자바 핵심 라 이브 러 리 의 유형 안전 을 확보 하기 위 한 것 입 니 다.
클래스 로 더 는 로 딩 류 뿐만 아니 라 안전 의 가장 기본 적 인 장벽 이기 도 합 니 다.
부모 위탁 체 제 는 대리 모델 의 하나 이다.
모든 종류의 로 더 가 부모 위탁 체 제 를 사용 하 는 것 은 아니다.
tomcat 서버 클래스 로 더 도 프 록 시 모드 를 사용 합 니 다.다른 것 은 먼저 어떤 종 류 를 불 러 오 려 고 시도 하 는 것 입 니 다.부모 클래스 로 더 를 불 러 오 는 프 록 시 를 찾 지 못 하면.이것 은 일반 종류의 로 더 순서 와 반대 이다.
사용자 정의 클래스 로 더 프로 세 스:
계승:java.lang.ClassLoader
우선 요청 한 형식 이 네 임 스페이스 에 불 러 왔 는 지 확인 하고 불 러 왔 으 면 되 돌려 줍 니 다.
위임 클래스 는 부모 클래스 로 더 에 요청 을 불 러 옵 니 다.부모 클래스 로 더 가 완료 되면 부모 클래스 로 더 가 불 러 온 Class 인 스 턴 스 를 되 돌려 줍 니 다.
이 종류의 로 더 의 findClass()방법 을 호출 하고 사제 가 해당 하 는 바이트 코드 를 가 져 옵 니 다.가 져 오 면 defineClass()가 져 오 는 형식 을 방법 영역 으로 가 져 옵 니 다.대응 하 는 바이트 코드 를 가 져 오지 못 하거나 다른 이유 로 실 패 했 을 경우,로드 클래스(),로드 클래스()에 이상 을 되 돌려 주 고,로드 프로 세 스 를 종료 합 니 다.
주:두 개의 로 더 에 불 러 온 같은 클래스 입 니 다.Jvm 은 같은 클래스 라 고 생각 하지 않 습 니 다.
예제 코드 는 다음 과 같다.
package com.test;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
/**
*
* @author We.lxk
*
*/
public class FileSystemClassLoader extends ClassLoader{
private String rootDir;
public FileSystemClassLoader(String rootDir) {
this.rootDir = rootDir;
}
private byte[] getClassData(String classname){ //com.test.User -> rootDir/com/test/User
String path = rootDir +"/"+classname.replace(".", "/")+".class";
//IOUtils
InputStream is = null;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try{
is = new FileInputStream(path);
byte[] buffer = new byte[1024];
int temp = 0;
while((temp=is.read(buffer))!=-1){
baos.write(buffer, 0, temp);
}
return baos.toByteArray();
}catch(Exception e){
e.printStackTrace();
return null;
}finally{
try {
if(is!=null)
is.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
if(baos!=null)
baos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
Class<?> c = findLoadedClass(name);
// 。 , 。
if(c!=null){
return c;
}else{
ClassLoader parent = this.getParent();
try{
//System.out.println("hello");
c = parent.loadClass(name); //
}catch(Exception e){
//e.printStackTrace();
}
if(c!=null){
return c;
}else{
byte[] classData = getClassData(name);
if(classData==null){
throw new ClassNotFoundException();
}else{
c = defineClass(name, classData, 0, classData.length);
}
}
}
return c;
}
}
테스트 코드:
package com.test;
/**
* FileSystemClassLoader
* @author We.lxk
*
*/
public class Demo03 {
public static void main(String[] args) throws Exception {
FileSystemClassLoader loader = new FileSystemClassLoader("D:/myJava");
FileSystemClassLoader loader2 = new FileSystemClassLoader("D:/myJava");
Class<?> c = loader.loadClass("com.test.Demos");
Class<?> c2 = loader.loadClass("com.test.Demos");
Class<?> c3 = loader2.loadClass("com.test.Demos");
Class<?> c4 = loader2.loadClass("java.lang.String");
Class<?> c5 = loader.loadClass("com.test.Demo");
System.out.println(c.hashCode()+" "+c.getClassLoader());
System.out.println(c2.hashCode()+" "+c2.getClassLoader());
System.out.println(c3.hashCode()+" "+c3.getClassLoader());
System.out.println(c4.hashCode()+" "+c4.getClassLoader());
System.out.println(c5.hashCode()+" "+c5.getClassLoader());
//System.out.println(.getClassLoader());
}
}
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Is Eclipse IDE dying?In 2014 the Eclipse IDE is the leading development environment for Java with a market share of approximately 65%. but ac...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.