Java ClassLoader 란 무엇입니까?


174

몇 가지 간단한 문장에서 Java ClassLoader는 무엇이며 언제 사용되며 왜 그런가?

좋아, 나는 위키 기사를 읽었다. ClassLoader는 클래스를로드합니다. 확인. jar 파일을 포함하고 가져 오면 ClassLoader가 작업을 수행합니다.

이 ClassLoader를 왜 귀찮게해야합니까? 나는 그것을 사용한 적이 없으며 그것이 존재하는지 몰랐다.

문제는 ClassLoader 클래스가 존재하는 이유는 무엇입니까? 또한 실제로 어떻게 사용합니까? (사례가 존재합니다.)


예를 들어, 이해하지 못하는 특정 부분, 익숙한 다른 언어와의 관련성 등을 가리켜 질문을 좁 히면 더 나은 결과를 얻을 수 있습니다.
JRL

75
개념을 설명하기 위해 몇 가지 간단한 문장을 찾는 누군가의 관점에서 볼 때 이것은 완전히 합리적인 질문입니다
oxbow_lakes

이 비디오가 흥미로울 것입니다 : 당신은 정말로 클래스 로더를 얻습니까?
asmaier

답변:


231

이 멋진 튜토리얼 에서 가져 왔습니다.

자극

C 및 C ++와 같이 정적으로 컴파일 된 프로그래밍 언어로 작성된 응용 프로그램은 시스템 고유의 명령어로 컴파일되어 실행 파일로 저장됩니다. 코드를 실행 가능한 원시 코드로 결합하는 프로세스를 링크라고합니다. 별도로 컴파일 된 코드를 공유 라이브러리 코드와 병합하여 실행 가능한 응용 프로그램을 만듭니다. 이것은 Java와 같이 동적으로 컴파일 된 프로그래밍 언어에서 다릅니다. Java에서 Java 컴파일러에 의해 생성 된 .class 파일은 JVM (Java Virtual Machine)에로드 될 때까지 그대로 유지됩니다. 즉, 링크 프로세스는 런타임시 JVM에 의해 수행됩니다. 클래스는 '필요한'기준으로 JVM에로드됩니다. 로드 된 클래스가 다른 클래스에 종속되면 해당 클래스도로드됩니다.

Java 응용 프로그램이 시작되면 실행할 첫 번째 클래스 (또는 응용 프로그램의 진입 점)는 main ()이라는 공용 정적 void 메서드가있는 클래스입니다. 이 클래스에는 일반적으로 다른 클래스에 대한 참조가 있으며 참조 된 클래스를로드하려는 모든 시도는 클래스 로더에 의해 수행됩니다.

이 재귀 클래스 로딩과 일반적인 클래스 로딩 아이디어를 얻으려면 다음과 같은 간단한 클래스를 고려하십시오.

public class HelloApp {
   public static void main(String argv[]) {
      System.out.println("Aloha! Hello and Bye");
   }
}

로드되는 클래스를 인쇄하도록 -verbose : class 명령 행 옵션을 지정하여이 클래스를 실행하면 다음과 같은 출력이 표시됩니다. 목록이 너무 길어서 여기에 표시 할 수 없기 때문에 이것은 부분 출력 일뿐입니다.

prmpt>java -verbose:class HelloApp



[Opened C:\Program Files\Java\jre1.5.0\lib\rt.jar]
[Opened C:\Program Files\Java\jre1.5.0\lib\jsse.jar]
[Opened C:\Program Files\Java\jre1.5.0\lib\jce.jar]
[Opened C:\Program Files\Java\jre1.5.0\lib\charsets.jar]
[Loaded java.lang.Object from shared objects file]
[Loaded java.io.Serializable from shared objects file]
[Loaded java.lang.Comparable from shared objects file]
[Loaded java.lang.CharSequence from shared objects file]
[Loaded java.lang.String from shared objects file]
[Loaded java.lang.reflect.GenericDeclaration from shared objects file]
[Loaded java.lang.reflect.Type from shared objects file]
[Loaded java.lang.reflect.AnnotatedElement from shared objects file]
[Loaded java.lang.Class from shared objects file]
[Loaded java.lang.Cloneable from shared objects file]
[Loaded java.lang.ClassLoader from shared objects file]
[Loaded java.lang.System from shared objects file]
[Loaded java.lang.Throwable from shared objects file]
.
.
.
[Loaded java.security.BasicPermissionCollection from shared objects file]
[Loaded java.security.Principal from shared objects file]
[Loaded java.security.cert.Certificate from shared objects file]
[Loaded HelloApp from file:/C:/classes/]
Aloha! Hello and Bye
[Loaded java.lang.Shutdown from shared objects file]
[Loaded java.lang.Shutdown$Lock from shared objects file]

보다시피, 애플리케이션 클래스 (HelloApp)에 필요한 Java 런타임 클래스가 먼저로드됩니다.

Java 2 플랫폼의 클래스 로더

Java 프로그래밍 언어는 계속해서 애플리케이션 개발자의 삶을 편하게 만들어줍니다. 이는 기본 메커니즘의 구현 세부 사항이 아닌 비즈니스 로직에 집중할 수 있도록하여 생활을 단순화하는 API를 제공함으로써 수행됩니다. 이는 Java 플랫폼의 성숙도를 반영하기 위해 최근 J2SE 1.5에서 J2SE 5.0으로 변경 한 것이 분명합니다.

JDK 1.2부터 JVM에 내장 된 부트 스트랩 클래스 로더는 Java 런타임의 클래스를로드합니다. 이 클래스 로더는 부트 클래스 경로에있는 클래스 만로드하며, 신뢰할 수있는 클래스이기 때문에 신뢰할 수없는 클래스와 마찬가지로 유효성 검사 프로세스가 수행되지 않습니다. JVM에는 부트 스트랩 클래스 로더 외에 표준 확장 API에서 클래스를로드하는 확장 클래스 로더와 일반 클래스 경로 및 애플리케이션 클래스에서 클래스를로드하는 시스템 클래스 로더가 있습니다.

클래스 로더가 두 개 이상 있기 때문에 루트가 부트 스트랩 클래스 로더 인 트리에 표시됩니다. 각 클래스 로더에는 상위 클래스 로더에 대한 참조가 있습니다. 클래스 로더가 클래스를로드하도록 요청되면 항목 자체를로드하기 전에 상위 클래스 로더를 참조합니다. 부모는 차례로 부모와 상담합니다. 따라서 모든 조상 클래스 로더가 현재 클래스 로더와 관련된 클래스를 찾을 수없는 경우에만 발생합니다. 즉, 위임 모델이 사용됩니다.

java.lang.ClassLoader 클래스

java.lang.ClassLoaderJVM이 동적으로 클래스를로드 방식을 확장해야하는 응용 프로그램에 의해 서브 클래스화할 수 추상 클래스입니다. java.lang.ClassLoader새 클래스 로더를 인스턴스화 할 때 생성자 와 하위 클래스의 생성자 를 사용하여 부모를 지정할 수 있습니다. 상위를 명시 적으로 지정하지 않으면 가상 머신의 시스템 클래스 로더가 기본 상위로 지정됩니다. 다시 말해 ClassLoader 클래스는 위임 모델을 사용하여 클래스와 리소스를 검색합니다. 따라서 클래스 로더의 각 인스턴스에는 연관된 상위 클래스 로더가 있으므로 클래스 또는 자원 찾기를 요청하면 클래스 또는 자원 자체를 찾기 전에 태스크가 상위 클래스 로더에 위임됩니다. loadClass()ClassLoader 의 메소드는 클래스를로드하기 위해 호출 될 때 다음 태스크를 순서대로 수행합니다.

클래스가 이미로드되어 있으면 반환합니다. 그렇지 않으면 새 클래스에 대한 검색을 상위 클래스 로더에 위임합니다. 부모 클래스 로더가 클래스 를 찾지 못하면 loadClass()메소드 findClass()를 호출하여 클래스 를 찾아서로드하십시오. finalClass()현재의 클래스 로더의 클래스에 대한 방법 검색이 클래스는 부모 클래스 로더에 의해 발견되지 않은 경우.


원래 기사에 더 많은 내용이 있으며 자체 네트워크 클래스 로더를 구현하는 방법을 보여줍니다.이 클래스는 왜 (및) 방법에 대한 질문에 대답합니다. API 문서 도 참조하십시오 .


47

대부분의 Java 개발자는 클래스 로더를 명시 적으로 사용할 필요가 없습니다 (JAR에 번들로 제공 될 때 리소스가로드되도록하는 것 제외).

ClassLoader는 대규모 시스템 및 서버 응용 프로그램에서 다음과 같은 작업을 수행하는 데 사용됩니다.

  • 시스템 모듈화 및 런타임에 모듈로드, 언로드 및 업데이트
  • 다른 버전의 API 라이브러리 (예 : XML 파서)를 동시에 사용
  • 동일한 JVM 내에서 실행중인 다른 애플리케이션을 격리합니다 (예 : 정적 변수를 통해 서로 간섭하지 않도록 함)

29

문제는 "이 ClassLoader 클래스가 존재하는 이유는 무엇입니까?"입니다.

글쎄, 대부분 잘못되면 문제를 해결할 수 있습니다 :-).

응용 프로그램을 작성하고 JAR로 컴파일하고 몇 가지 추가 라이브러리 JAR을 포함하는 한 클래스 로더에 대해 알 필요가 없으며 작동합니다.

여전히 클래스 로더와 클래스 로딩에 대해 조금 알고 있으면 뒤에서 일어나는 일을 더 잘 이해할 수 있습니다. 예를 들어, 클래스가로드 될 때 "정적 이니셜 라이저"가 실행되므로 클래스 실행시기를 이해하려면 클래스 로더가로드시기를 결정하는 방법을 알아야합니다.

또한 .. 실제로 어떻게 사용합니까?

간단한 경우에는 필요하지 않습니다. 그러나 런타임에서 코드의 출처를 명시 적으로 제어하여 코드를 동적으로로드해야하는 경우 (예 : 네트워크로드, 컴파일 타임에 사용할 수없는 플러그인로드 등) 더 많은 작업이 필요할 수 있습니다. 그런 다음 예를 들어 자신 만의 클래스 로더를 작성할 수 있습니다. 링크에 대한 다른 답변을 참조하십시오.


14

ClassLoaderJava에서 Java로 클래스 파일을로드하는 데 사용되는 클래스입니다. Java 코드는 javac컴파일러에 의해 클래스 파일로 컴파일되고 JVM은 클래스 파일로 작성된 바이트 코드를 실행하여 Java 프로그램을 실행합니다.

ClassLoader는 파일 시스템, 네트워크 또는 기타 소스에서 클래스 파일을로드합니다. Java, Bootstrap , ExtensionSystem 또는 Application 클래스 로더 에는 세 가지 기본 클래스 로더가 사용됩니다 .

클래스 로더


ClassLoader 작동 방식

## JVM과의 ClassLoader 상호 작용 여기에 이미지 설명을 입력하십시오

더 많은 @ : how-classloader-works-in-java.html


6

클래스 로더는 JVM의 기능적 구성 요소로, 클래스 데이터를 '.class'파일에서 또는 네트워크를 통해 힙의 메소드 영역으로로드합니다.

JVM의 필수 부분처럼 보이지만 최종 Java 사용자는 왜 걱정해야합니까? 이유는 다음과 같습니다.

각 클래스 로더에는 자체 네임 스페이스가 있으며 특정 클래스 로더가 호출 한 클래스는 네임 스페이스에 들어갑니다.

서로 다른 두 개의 클래스 로더가 호출 한 클래스는 서로에 대한 가시성을 가지지 않으므로 보안이 강화됩니다.

클래스 로더 부모 자식 위임 메커니즘은 권한이없는 코드로 Java API 클래스를 해킹 할 수 없도록합니다.

자세한 내용은 여기 를 참조 하십시오


1

클래스 로더는 계층 적입니다. 클래스는 이미 JVM에서 실행중인 클래스에서 이름으로 참조 될 때 JVM에 도입됩니다.

첫 클래스는 어떻게로드 되었습니까?
첫 번째 클래스는 클래스에 static main()선언 된 메소드 의 도움으로로드됩니다 . 이후에로드 된 모든 클래스는 이미로드되어 실행중인 클래스에 의해로드됩니다.

클래스 로더는 네임 스페이스를 만듭니다. 모든 JVM 에는 기본 (또는 부트 스트랩) 클래스 로더 라고하는 JVM 내에 임베드 된 하나 이상의 클래스 로더가 포함됩니다 . 이것이 한 가지이며, 우리는 비 primordial 클래스 로더를 살펴볼 것입니다. JVM에는 기본 클래스 로더 대신 사용자 정의 클래스 로더를 사용할 수 있도록 후크가 있습니다. 다음은 JVM에서 작성된 클래스 로더입니다.

부트 스트랩 (primordial) 이 클래스 로더는 다시로드 할 수 없습니다. JDK 내부 클래스 인 java. * 패키지를로드합니다 (일반적으로 rt.jar 및 i18n.jar를로드 함). Extesions이 클래스 로더는 다시로드 할 수 없습니다. JDK 확장 디렉토리 (일반적으로 JRE의 lib / ext)에서 jar 파일을로드합니다. 시스템이 클래스 로더는 다시로드 할 수 없습니다. 시스템 클래스 경로에서 클래스를로드합니다.

http://www.sbalasani.com/2015/01/java-class-loaders.html


1

ClassLoader 클래스가 존재하는 이유를 물을 때 이유는 매우 간단 합니다. 런타임에 클래스 파일찾아서로드하는 클래스 입니다.

자세히 설명하겠습니다.

JVM에서 모든 클래스는의 일부 인스턴스에 의해로드됩니다 java.lang.ClassLoader. 일반적인 Java 프로그램 실행 java <classname>명령 으로 새 JVM이 시작될 때마다 첫 번째 단계는 올바른 작동 java.lang.Object및 기타 런타임 클래스 ( rt.jar)에 필요한 모든 키 클래스를 메모리에로드하는 것 입니다.

이제 ClassLoader에는 세 부분이 있습니다.

  • BootstrapClassLoader메모리에 이러한 클래스를 사용할 즉, 부하에게 이러한 클래스를 만들기위한 책임이 있습니다.

  • 다음 작업은 응용 프로그램이 올바르게 작동하도록 외부 라이브러리 / JAR을 메모리에로드하는 것입니다. 는 ExtClassLoader이 작업을 담당합니다. 이 클래스 로더는 java.ext.dirs 경로에 언급 된 모든 .jar 파일을로드합니다.

  • 세 번째이자 주요 클래스 로더는 AppClassLoader입니다. 애플리케이션 클래스 로더는 java.class.path 시스템 특성에 언급 된 클래스 파일의로드를 담당합니다.

또한 기본 클래스 로더 구현을 재정 의하여 유용하고 흥미로운 방법으로 JVM을 사용자 정의 할 수 있으므로 클래스 파일이 시스템으로 가져 오는 방법을 완전히 재정의 할 수 있습니다.

여기에 이미지 설명을 입력하십시오

Java Class Loader 에 대해 자세히 알아 보려면 확인하십시오 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.