IT이야기

스레드의 컨텍스트 클래스 로더와 일반 클래스 로더의 차이

cyworld 2022. 7. 2. 13:16
반응형

스레드의 컨텍스트 클래스 로더와 일반 클래스 로더의 차이

스레드의 컨텍스트 클래스 로더와 일반 클래스 로더의 차이점은 무엇입니까?

즉, 만약Thread.currentThread().getContextClassLoader()그리고.getClass().getClassLoader()다른 클래스 로더 개체를 반환합니다. 어떤 개체가 사용될까요?

이는 원래 질문에 대한 답변은 아니지만 질문이 높은 순위를 차지하고 링크되어 있기 때문에ContextClassLoaderquery, 콘텍스트클래스 로더를 언제 사용해야 하는지에 대한 관련 질문에 대답하는 것이 중요하다고 생각합니다.간단한 답변: 컨텍스트 클래스 로더를 사용하지 마십시오!단, 로 설정합니다.getClass().getClassLoader()누락된 메서드를 호출해야 할 경우ClassLoader파라미터를 지정합니다.

한 클래스의 코드가 다른 클래스를 로드하도록 요청하면 사용하는 올바른 클래스 로더는 호출자 클래스와 동일한 클래스 로더입니다(즉,getClass().getClassLoader()이것은 새로운 클래스의 인스턴스를 처음 작성하거나 정적 메서드를 호출하거나 정적 필드에 액세스할 때 JVM이 자체적으로 수행하는 작업이기 때문에 99.9%의 작업 방식입니다.

리플렉션을 사용하여 클래스를 만드는 경우(예를 들어 구성 가능한 이름 있는 클래스를 역직렬화 또는 로드하는 경우) 리플렉션을 수행하는 라이브러리는 항상 응용 프로그램에 어떤 클래스 로더를 사용할지 물어봅니다.ClassLoader어플리케이션의 파라미터로 지정합니다.어플리케이션(구축이 필요한 모든 클래스를 알고 있는 것)은 이 어플리케이션을 통과해야 합니다.getClass().getClassLoader().

클래스 로더를 얻는 다른 방법은 올바르지 않습니다.라이브러리가 , 등의 해크를 사용하는 경우 또는 API의 결함으로 인한 버그입니다.기본적으로는Thread.getContextClassLoader()그 이유는 단지 누가 설계했든 간에ObjectInputStreamAPI가 승인하지 않았습니다.ClassLoader이 실수는 지금까지 Java 커뮤니티를 괴롭히고 있습니다.

즉, 많은 JDK 클래스는 몇 가지 해크 중 하나를 사용하여 사용할 클래스 로더를 추측합니다.일부에서는ContextClassLoader(공유 스레드 풀에서 서로 다른 앱을 실행하거나 를 종료하면 실패합니다.ContextClassLoader null일부에서는 (클래스의 다이렉트 발신자가 라이브러리인 경우 실패), 시스템클래스 로더를 사용하는 경우도 있습니다(클래스의 직접 발신자가 라이브러리인 경우).CLASSPATH또는 부트스트랩클래스 로더입니다.또, 상기의 테크놀로지의 예측 불가능한 편성을 사용하는 경우도 있습니다(그 때문에, 상황은 한층 더 혼란스러울 뿐입니다).이것은 많은 눈물을 흘리고 이를 가는 결과를 초래했다.

이러한 API를 사용할 경우 먼저 클래스 로더를 파라미터로 받아들이는 메서드의 오버로드를 찾아봅니다.합리적인 방법이 없는 경우, 다음 설정을 시도합니다.ContextClassLoaderAPI 호출 전(및 나중에 재설정):

ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
try {
    Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
    // call some API that uses reflection without taking ClassLoader param
} finally {
    Thread.currentThread().setContextClassLoader(originalClassLoader);
}

각 클래스는 자체 클래스 로더를 사용하여 다른 클래스를 로드합니다.그래서 만약에ClassA.class레퍼런스ClassB.class그리고나서ClassB클래스 로더의 클래스 패스에 있어야 합니다.ClassA또는 그 부모.

스레드 컨텍스트클래스로더는 현재 스레드의 현재 클래스 로더입니다.오브젝트는 다음 클래스에서 만들 수 있습니다.ClassLoaderC그리고 나서 소유자의 스레드로 넘어갔다.ClassLoaderD. 이 경우 오브젝트는Thread.currentThread().getContextClassLoader()자체 클래스 로더에서 사용할 수 없는 리소스를 로드하는 경우 직접 로드합니다.

infoworld.com에 => 어떤 ClassLoader를 사용해야 하는지 설명하는 기사가 있습니다.

(1)

스레드 컨텍스트클래스로더는 클래스 로딩 위임 방식 주위에 백도어를 제공합니다.

예를 들어 JNDI는 guts가 rt.jar의 부트스트랩클래스(J2SE 1.3부터 시작)에 의해 구현되지만 이들 핵심 JNDI 클래스는 독립 벤더가 구현한 JNDI 프로바이더를 로드하여 애플리케이션의 클래스 경로에 배치될 수 있습니다.이 시나리오에서는 부모 클래스 로더(이 경우 초기 클래스 로더)가 자녀 클래스 로더(시스템 클래스 로더 등) 중 하나에 표시되는 클래스를 로드해야 합니다.통상의 J2SE 위임은 기능하지 않으며, 회피책은 코어 JNDI 클래스에서 스레드콘텍스트로더를 사용하도록 하는 것입니다.따라서 클래스 로더 계층을 통해 적절한 위임과 반대 방향으로 효과적으로 '터널링'하는 것입니다.

(2) 동일한 소스:

이 혼란은 당분간 Java에 머물 것입니다.모든 종류의 동적 리소스 로딩이 포함된 J2SE API를 사용하여 어떤 로드 전략을 사용하는지 추측해 보십시오.다음은 샘플입니다.

  • JNDI는 컨텍스트클래스로더를 사용합니다.
  • Class.getResource() 및 Class.forName()은 현재 클래스 로더를 사용합니다.
  • JAXP는 컨텍스트클래스로더를 사용합니다(J2SE 1.4 이후).
  • java.displaces를 클릭합니다.ResourceBundle은 호출자의 현재 클래스 로더를 사용합니다.
  • java.protocol.handler.pkgs 시스템 속성을 통해 지정된 URL 프로토콜 핸들러는 부트스트랩 및 시스템클래스로더에서만 검색됩니다.
  • Java Serialization API는 기본적으로 호출자의 현재 클래스로더를 사용합니다.

@David Rousel 응답에 추가하여 여러 클래스 로더에 의해 클래스가 로드될 수 있습니다.

클래스 로더의 동작에 대해 설명합니다.

javarevisited의 javin paul 블로그에서 :

enter image description here

enter image description here

ClassLoader는 3가지 원칙을 따릅니다.

위임 원칙

클래스는 필요에 따라 Java로 로드됩니다.Abc.class라는 응용 프로그램 고유의 클래스가 있다고 가정하면 이 클래스의 로딩에 대한 첫 번째 요구는 Application ClassLoader에 도달하고 부모 Extension ClassLoader는 Primordial 또는 Bootstrap 클래스 로더에 위임됩니다.

  • Bootstrap ClassLoader는 rt.jar에서 표준 JDK 클래스 파일을 로드하는 역할을 하며 Java에서 모든 클래스 로더의 부모입니다.부트스트랩 클래스 로더에 부모가 없습니다.

  • Extension ClassLoader는 클래스 로딩 요구를 부모 부트스트랩에 위임하고 실패 시 jre/lib/ext 디렉토리 또는 java.ext.dirs 시스템속성이 가리키는 다른 디렉토리에서 클래스를 로드합니다.

  • 시스템 또는 응용 프로그램클래스 로더이며 CLASSPATH 환경변수, -classpath 또는 -cp 명령줄 옵션, JAR 내의 Manifest 파일의 Class-Path 속성에서 응용 프로그램별 클래스를 로드합니다.

  • 응용 프로그램클래스 로더는 Extension Class Loader의 자식이며 에 의해 구현됩니다.sun.misc.Launcher$AppClassLoader학급.

메모: 부트스트랩클래스 로더를 제외한 모든 Java 클래스 로더는 주로 C에서 네이티브 언어로 구현됩니다.java.lang.ClassLoader.

가시성의 원칙

가시성 원칙에 따라 Child Class Loader는 Parent Class Loader에 의해 로드된 클래스를 볼 수 있지만 그 반대는 사실이 아닙니다.

고유성의 원칙

이 원칙에 따라 부모에 의해 로드된 클래스는 자식 클래스 로더에 의해 다시 로드되지 않아야 합니다.

언급URL : https://stackoverflow.com/questions/1771679/difference-between-threads-context-class-loader-and-normal-classloader

반응형