-------------------------------------------------------------------------------------------------
출처: http://testing.pe.kr/xe/322
-------------------------------------------------------------------------------------------------
Class loader delegation model을 굳이 우리말로 바꾸자면 Class loader 위임 모델이라고 할 수 있다.
즉, 이것은 로딩 요청을 위계적으로 전달하는 방식을 나타내는 것으로 이해할 수 있다.
이 모델을 간단하게 말하자면 class를 로딩할 때 자신의 Class loader의 위계구조의 위쪽
즉, 부모의 class loader에게 로딩을 위임하는 것이라 할 수 있다.
Class loader의 위계구조는 위의 그림과 같다.
쉽게 말해 Bootstrap-Extension-Application의 구조를 가지게 된다.
Class loader들이 class를 로딩하게 되면 하나의 delegation parent와 함께 생성되고
"Cache → Parent → Self"의 순서로 해당 class를 확인하게 된다.
Class loader가 로딩을 하게 될 때 가장 먼저 하게 되는 일은 해당 Class가 이미 로딩이 되어 있는지를
확인하는 것이다. 만약 로딩이 되어 있다면 메모리에 Cache되어 있을 것이고 이 경우 해당 class를
반환하게 된다. 만약 로딩이 되지 않았다면 부모(parent)에게 class를 로딩하게 위임을 하게 되고
부모가 Class를 로딩할 수 없다면 자신(self class loader)이 클래스를 탐색하게 된다.
이렇게 로딩되는 경우 class를 로딩할 확률은 delegation model의 상위로 갈수록 높아진다.
가장 상위에 있는 bootstrap class loader는 JVM의 수행을 위한 핵심적인 class만을 로딩하게 되고,
가장 기본적인 class들의 버전이 정확하게 일치하는지를 확인한다.
또한 각 class가 누구에 의해 로딩이 되었는지에 대한 정보도 제공하고 있다.
(참고로 이 정보는 자신을 포함한 상위의 class loader가 로딩한 것만 확인이 가능하고
자신의 하위의 loader가 로딩한 것에 대한 정보는 알 수 없다.)
Bootstrap loader는 VM의 일부로 구현되기 때문에 다른 class loader와는 달리 자바 코드로
인스턴스화 할 수 없다. 이 class loader는 JVM의 수행을 위한 핵심 시스템 class를 로딩하는데
일반적으로 $JAVA_HOME/jre/lib에 있는 JAR파일들이 그 대상이 된다.
이를 변경하기 위해서는 -Xbootclasspath옵션을 사용하면 된다.
Extension class loader는 Bootstrap의 바로 하위에 있는 class loader이다.
주로$JAVA_HOME/ jre/lib/ext에 위치한 JAR파일이 그 대상이 된다.
Application class loader는 $CLASSPATH에 지정된 경로에서 class를 로딩한다.
이 class loader는 user-defined class loader의 부모가 된다.
결국 delegation model에 따라class를 로딩하게 때문에 그리고 각 loader가 class를 로딩하는 위치는
정해져 있기 때문에 class loading시 가장 먼저 찾게 되는 경로는 $JAVA_HOME/jre/lib가 되고
그 다음으로는 $JAVA_HOME/ jre/lib/ext, $CLASSPATH의 순서가 된다.
그러므로 가급적 사용자가 정의한 class의 경우는 Core class가 위치한 경로를 피하는 것이 좋다.
Application Server의 경우 delegation model의 위계구조는 아래의 그림처럼 다소 달라진다.
그러나 이것 역시 delegation model을 사용하기 때문에 class를 로딩할 때 parent에게 loading의 의무를
위임하고 parent가 할 수 없는 경우 자신이 class를 로딩하게 된다.
Bootstrap class loader는 JVM의 Class loder와 같이 최상위 Class loader이며,
여기에서는 System Class loader의 parent가 된다.
System class loader는 Application Server의 core class의 대부분을 로딩하는 역할을 한다.
이 loader는 env의 classpath변수를 무시하는 별도의 옵션을 주지 않는 이상 $CLASSPATH에
위치한 class파일들이 그 대상이 된다.
- 규칙 1. 클래스 로더는 계층 구조를 형성 - 규칙 2. 클래스는 필요 시점에 로딩된다. - 규칙 3. 클래스 A를 로팅할 때는, 클래스 A를 호출한 클래스 B의 클래스 로더가 인스턴스 로딩을 담당한다. - 규칙 4. 클래스 유일성 식별: 클래스명+패키지명+클래스로더 인스턴스 - 규칙 5. 클래스 로더에는 명시적인 Unload가 없다. 대신 GC될 때 Unload 된다. |
j2se1.4 API doc의 ClassLoader의 내용
클래스 로더는 클래스를 적재(load)하는 역할을 하는 객체이다. classloader 클래스는 추상클래스이다. 클래스의 이름을 받으면 클래스로더는 해당 클래스에 대한 정의를 구성하는 데이터를 찾거나 생산하려고 시도할 것이다. 전형적인(정해진?) 전략은 받은 이름을 파일 이름으로 바꾸고 나서 클래스의 이름에 해당하는 “class file”을 파일시스템으로부터 읽는다.
모든 클래스 객체는 자신을 정의한 ClassLoader에 대한 참조를 가지고 있다. array 클래스의 Class객체는 class loader에 의해서 생성되지 않고 자바 런타임에 의해 요구되어질 때마다 자동적으로 생성된다. array 클래스에 Class.getClassLoader()를 실행하면 배열 요소 타입에 해당하는 클래스 로더가 리턴된다. 배열의 요소가 원시형이면 해당 배열 클래스는 클래스 로더가 없다.
응용프로그램은 자바 VM이 동적으로 클래스를 로드하는 방식을 확장하기 위한 목적으로 ClassLoader의 하위클래스를 구현한다. 클래스 로더는 보통, 보안 도메인을 지정하기 위하여 보안 관리자들에 의해 사용된다.
ClassLoader는 클래스와 자원들을 찾기 위하여 위임(delegation)모델을 사용한다. 각 ClassLoader는 연관된 부모 클래스가 있다. 클래스나 자원(resource)를 찾으라는 요구를 받으면 ClassLoader 객체는 자신이 찾으려고 하기 이전에 부모 클래스 로더에 작업을 위임한다.
VM에 내장된 클래스 로더 – “부트스트랩 클래스 로더(bootstrap class loader)” 는 부모 클래스로더를 가지고 있지 않으며, ClassLoader 객체의 부모로서 작업을 수행한다.
보통 자바 VM은 플랫폼 의존적인 방식으로 작동해, 로컬 파일 시스템으로부터 클래스들을 올리게 된다.
예를 들면 유닉스 시스템에서는 클래스패스 환경변수에 명시된 디렉토리로부터 클래스들을 읽어들인다. 그러나 어떤 클래스들은 파일로부터 기인하지 않는다. 네트워크와 같은 리소스로부터 발생하거나 애플리케이션에 의해 생성될 수도 있다. defileClass 메소드는 일련의 바이트 배열을 Class 클래스의 객체로 바꾸어 준다. 이렇게 새로 정의된 클래스의 객체는 Class.newInstance를 사용해서 생성할 수 있다.
클래스 로더에 의해 생성된 객체의 메소드와 생성자는 다른 클래스들을 참조할 수도 있다. 참조된 클래스(들)을 결정하기 위해서, 자바 VM은 그 클래스를 처음에 생성했던 클래스로더의 loadClass메소드를 실행한다.
예를 들어 애플리케이션은 서버로부터 클래스 파일들을 다운로드 받기 위해서 네트워크 클래스 로더를 생성할 수 있다. 아래 예제 코드를 보자.
ClassLoader loader = new NetworkClassLoader(host, port);
네트워크 클래스 로더의 subclass는 네트워크로부터 클래스를 load 하기 위해 findclass와 loadClassData 메소드를 정의해야 한다. 클래스를 생성하는 바이트코드를 다운로드 받으면 클래스 로더는 클래스 객체를 생성하기 위해 defineClass 메소드를 사용해야 한다. 간단한 구현은 아래와 같다.
class NetworkClassLoader extends ClassLoader {
public Class findClass(String name) {
private byte[] loadClassData(String name) { |
'IT_Programming > Java' 카테고리의 다른 글
[펌] 리플렉션 API를 사용하여 동적으로 교체 가능한 코드 작성하기 (0) | 2010.11.19 |
---|---|
파일 복사하는 소스코드 (0) | 2010.11.19 |
[펌] Java AWT:Lightweight UI Framework (0) | 2010.10.08 |
[펌] JNI - Package 안에서 JNI 사용하기 (JNI IN PACKAGE) (0) | 2010.09.29 |
사용자 정의 마우스 커서 만들기 (0) | 2010.09.27 |