Java 클래스 로더의 고급 핵심 지식에 대한 종합 분석 (상위 위임 모델, 소스 코드 분석. 사용자 정의 클래스 로더!)

첫째, 클래스 로딩 프로세스 검토

클래스 로딩 프로세스 : 로딩-> 연결-> 초기화. 연결 프로세스는 검증-> 준비-> 분석의 세 단계로 나눌 수 있습니다.

비 배열 클래스의 로딩 단계 (로딩 단계 동안 클래스의 바이너리 바이트 스트림을 가져 오는 작업 )는 가장 제어 가능한 단계입니다.이 단계를 완료하고 클래스 로더를 사용자 정의하여 바이트 스트림을 가져 오는 방법을 제어 할 수 있습니다. ( 클래스 로더의 loadClass () 메서드 재정의 ). 배열 유형은 클래스 로더에 의해 생성되지 않고 Java 가상 머신에 의해 직접 생성됩니다.

모든 클래스는 클래스 로더에 의해로드되며로드 기능은 .class 파일을 메모리에로드하는 것입니다.

둘째, 클래스 로더 요약

다른 클래스 로더가 Java에 의해 구현되고 모두 다음에서 상속 ClassLoader된다는 점을 제외하면 세 가지 중요한 것이 JVM에 빌드됩니다 .BootstrapClassLoaderjava.lang.ClassLoader

  1. BootstrapClassLoader (부트 클래스 로더) : C ++에 의해 실현되는 최상위 클래스 로딩은 %JAVA_HOME%/libjar 패키지 및 클래스 또는 디렉토리 또는 -Xbootclasspath클래스 경로에 지정된 모든 매개 변수 를로드 합니다.
  2. ExtensionClassLoader (확장 클래스 로더) : 주로 디렉토리 %JRE_HOME%/lib/extjar 패키지 및 클래스 디렉토리 또는 java.ext.dirsjar 패키지를 시스템 변수 지정 경로 아래 에로드합니다 .
  3. AppClassLoader (애플리케이션 클래스 로더) : 현재 애플리케이션 클래스 경로에서 모든 jar 패키지와 클래스를로드하는 사용자를위한 로더입니다.

참고 자료 : "Java 중급 및 고급 핵심 지식의 종합 분석"
이 학습 자료를 얻고 자하는 학생들은 여기를 클릭하여 무료로 얻을 수 있습니다. "" "" "" "" "" "" "" "" "

셋, 부모 위임 모델

1. 부모 위임 모델 소개

각 클래스에는 해당하는 클래스 로더가 있습니다. 시스템 ClassLoder은 함께 작업 할 때 기본적으로 부모 위임 모델을 사용합니다 . 즉, 클래스가로드되면 시스템은 먼저 현재 클래스가로드되었는지 여부를 확인합니다. 로드 된 클래스는 직접 반환됩니다. 그렇지 않으면로드를 시도합니다. 로드 할 때 요청은 먼저 상위 클래스 loader로 위임 loadClass()되므로 모든 요청은 결국 최상위 시작 클래스 loader로 전송되어야합니다 BootstrapClassLoader. 부모 클래스 로더가 그것을 처리 할 수 ​​없을 때, 그것을 처리하는 것은 자신에게 달려 있습니다. 상위 클래스 로더가 널이면 시작 클래스 로더가 BootstrapClassLoader상위 클래스 로더 로 사용 됩니다.

각 클래스 로딩에는 상위 클래스 로더가 있으며 다음 프로그램을 통해 확인합니다.

public class ClassLoaderDemo {
    
     
	public static void main(String[] args) {
    
     
		System.out.println("ClassLodarDemo's ClassLoader is " + 
ClassLoaderDemo.class.getClassLoader()); 
		System.out.println("The Parent of ClassLodarDemo's ClassLoader is " + 
ClassLoaderDemo.class.getClassLoader().getParent()); 
		System.out.println("The GrandParent of ClassLodarDemo's ClassLoader is " + 
ClassLoaderDemo.class.getClassLoader().getParent().getParent()); 
	} 
}

산출

ClassLodarDemo's ClassLoader is sun.misc.Launcher$AppClassLoader@18b4aac2 
The Parent of ClassLodarDemo's ClassLoader is 
sun.misc.Launcher$ExtClassLoader@1b6d3586 
The GrandParent of ClassLodarDemo's ClassLoader is null

AppClassLoader같은 부모 클래스 로더 ExtClassLoader
ExtClassLoader부모 클래스 로더가 null, null가 있다는 것을 의미하지 않습니다 ExtClassLoader 부모 클래스 로더를 , 하지만BootstrapClassLoader .

사실,이 부모의 번역은 다른 사람들이 오해하기 쉽습니다. 우리는 일반적으로 두 부모가 부모라는 것을 이해합니다. 여기서 부모는 "부모 세대"의 사람들이 더 많으며 실제로 어머니 클래스 로더와 아버지가 있다는 것이 아닙니다. ClassLoader. 또한 클래스 로더 간의 "상위-하위"관계는 상속을 통해 반영되지 않고 "우선 순위"에 의해 결정됩니다. 공식 API 문서는이 부분을 다음과 같이 설명합니다.

Java 플랫폼은 클래스로드를 위해 위임 모델을 사용합니다. 기본 아이디어는 모든 클래스 로더에 "부모"클래스 로더가 있다는 것입니다. 클래스를로드 할 때, 클래스 로더는 클래스 자체를 찾기 전에 먼저 클래스 검색을 상위 클래스 로더에 "위임"합니다.

2. 상위 위임 모델은 소스 코드 분석을 실현합니다.

부모 위임 모델 구현 코드가 명확 로직은 매우 간단 집중되어있다 , 관련 코드는 아래와 같습니다.java.lang.ClassLoaderloadClass()

private final ClassLoader parent; 
protected Class<?> loadClass(String name, boolean resolve) 
		throws ClassNotFoundException 
	{
    
     
		synchronized (getClassLoadingLock(name)) {
    
     
			// 首先,检查请求的类是否已经被加载过 
			Class<?> c = findLoadedClass(name); 
			if (c == null) {
    
     
				long t0 = System.nanoTime(); 
				try {
    
    
					if (parent != null) {
    
    //父加载器不为空,调用父加载器loadClass()方法处理 
						c = parent.loadClass(name, false); 
					} else {
    
    //父加载器为空,使用启动类加载器 BootstrapClassLoader加载 
						c = findBootstrapClassOrNull(name); 
					} 
				} catch (ClassNotFoundException e) {
    
     
					//抛出异常说明父类加载器无法完成加载请求 
				}
				
				if (c == null) {
    
     
					long t1 = System.nanoTime(); 
					//自己尝试加载 
					c = findClass(name); 
					
					// this is the defining class loader; record the stats 
					sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0); 
sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1); 
					sun.misc.PerfCounter.getFindClasses().increment(); 
				} 
			}
			if (resolve) {
    
     
				resolveClass(c); 
			}return c; 
	} 
}

3. 부모 위임 모델의 이점

상위 위임 모델은 Java 프로그램의 안정적인 작동을 보장하고 클래스의 반복적 인로드를 방지합니다 (JVM이 다른 클래스를 구별하는 방식은 클래스 이름을 기반으로 할뿐만 아니라 동일한 클래스 파일이 두 개의 다른 클래스를 생성하기 위해 다른 클래스 로더에 의해로드 됨). , 또한 Java의 핵심 API가 변조되지 않도록합니다. 부모 위임 모델이 없지만 각 클래스 로더가 자신의 단어를로드하는 경우 java.lang.Object클래스 를 작성하도록 호출되는 등 몇 가지 문제가 발생하면 프로그램이 실행될 때 시스템에 여러 다른 Object클래스 가 나타납니다 .

4. 부모 위임 모델을 사용하지 않으려면 어떻게합니까?

부모 위탁 메커니즘을 피하기 위해 자체 클래스 로더를 정의한 다음 다시 작성할 loadClass()수 있습니다.

네, 사용자 정의 클래스 로더

BootstrapClassLoader다른 클래스 로더를 제외하고는 Java로 구현되며 모두 Java에서 상속됩니다 java.lang.ClassLoader. 우리 자신의 클래스 로더를 사용자 정의하려면 분명히 상속해야합니다 ClassLoader.


참고 자료 : "Java 중급 및 고급 핵심 지식의 종합 분석"
이 학습 자료를 얻고 자하는 학생들은 여기를 클릭하여 무료로 얻을 수 있습니다. "" "" "" "" "" "" "

추천

출처blog.csdn.net/Java_Caiyo/article/details/111301247