Java 2 에서 부터 (1.3)는, Delegation Model 을 사용한다.

1. Class 가 이미 로드되어있는지 체크
2. Parent 의 Class Loader 에게 Class Load 하도록 위임함
3. 2 과정을 반복하며 최상위 Class Loader 까지 간다
4. 더이상 부모 ClassLoader 가 없으면, BootStrapClassLoader() 에게 요청한다
5. BootStrap 부터 다시 차근히 내려오면서 Class 로딩을 한다.
6. 클래스가 로드 되면 해당 클래스를 리턴한다
7. 이상이 ClassLoader.loadClass() 메커니즘이고, 만약 parent 에서 못찾으면,
    자신의 findClass() method 를 call 해서 클래스를 찾는다

Custom ClassLoader 를 생성할 때, 생성자에 parent classloader 를 지정할 수 있게 되어있음
만약 지정하지 않으면, 기본적으로 getSystemClassLoader() 를 통해, SystemClassLoader 를
parent 로 지정함. 이 system class loader 는 현재 invoking thread 의 context class loader 로 설정된다

* BootStrap 클래스로더 : Java Runtime Library 에 있는 클래스를 로딩하는 역할을 맡고 있음. 클래스로더 체인의
가장 첫번째임. 기본적으로 rt.jar 에 있는 클래스를 Bootstrap ClassLoader 가 로드 한다.

* 하나의 JVM 에 여러 클래스로더가 각각 같은 Package.Class 를 Load 하면, 각각의 인스턴스가 따로 생긴다.
결국, Java 에서의 클래스 생성은 "패키지, 클래스, 클래스로더" 의 3가지의 조합으로 구분되는 것이다

* Java2 의 표준 Runtime Library (jre/lib/rt.jar) 는 공개/내부사용 클래스 로더들이 있다
  - java.net.URLClassLoader
   파일, HTTP, FTP 등을 사용하여 Class 를 Load 할 수 있는 ClassLoader 임

  import java.net.URL;
  import java.net.URLClassLoader;
  
  public class FileSystemTest {
  
   public static void main(String[] args) throws Exception {
   URL[] urls = { new java.io.File("/usr/classes").toURL(); }
  
   URLClassLoader ucl = new URLClassLoader(urls);
   
   Class kalss = ucl.loadClass("javacan.exam.HelloWorld");
   Object obj = klass.newInstance();
   // obj를 사용하여 적절한 것을 한다.
   }
  }

  - BootStrap 클래스로더
   엄밀히 말해 Java 클래스로더가 아니고, 네이티브 로더로, Object 와 같은 코어 자바클래스를 VM 에 로딩할때 사용된다. sun.boot.class.path 프로퍼티에 정의 된 값을 사용하여 자바 런타임 라이브러리를 찾는다. 만약 명시적으로 지정하지 않으면 <JDK>/jre/lib/rt.jar 로 부터 런타임 클래스들을 로딩한다.
  JDK 1.0 이나 1.1.X 대는 CLASSPATH 나 -classpath 에 런타임을 추가해줬어야 하지만, Java2 부터는 BootStrap 클래스로더가 런타임라이브러리를 자동으로 로드해주므로 지정 할 필요가 없다.

  - sun.misc.Launcher$ExtClassLoader
   자바의 확장클래스를 로드할 때 사용한다. ExtClassLoader 는 URLClassLoader 를 상속하며, java.ext.dirs 프로퍼티에 지정한 디렉토리에 위치한 .jar 들로 부터 클래스를 읽어온다. 명시하지 않으면 기본적으로 <JDK>/jre/lib/ext 디렉토리에 있는 .jar 들을 읽어서 클래스를 로드한다

  - sun.misc.Launcher$AppClassLoader
   시스템 또는 어플리케이션 클래스로더라고 불린다. java.class.path 프로퍼티에 명시된 경로에서 코드를 로딩하는 클래스로더이다. URLClassLoader 를 상속한다. CLASSPATH 에 있는 디렉토리나 .jar 파일들은 모두 URL 로 변환되어 AppClassLoader 에게 전달된다.

   ClassLoader.getSystemClassLoader() 를 호출하면 이 클래스가 리턴된다. 개발자가 작성한 대부분의 클래스는 이 클래스로더를 통해 로드된다. AppClassLoader 는 부모 ClassLoader 로 ExtClassLoader 를 지정하고 있으므로, ext 디렉토리에 있는 jar 파일로 부터 클래스들을 로드할 수 있다.

  - sun.applet.AppletClassLoader
  
브라우저가 Applet 의 바이트코드를 다운로드 하고, 그 애플릿을 실행하기 위한 클래스를 로드하는 Class Loader 이다. URLClassLoader 를 상속받고 있어서, HTTP 나 FTP 등을 통해 클래스를 로드 가능 한 것이다. 그러나 IE 나 각 브라우저 별로, 애플릿 클래스로더를 구현하고 있는 경우가 있어, 브라우져 별로 동작이 다를 수 있다.

  - java.security.SecureClassLoader
   JVM 에 바이트코드를 로딩하고 사용하는데에 관한 보안을 제어하는 추상클래스로, URLClassLoader 를 포함한 ClassLoader 가 상속받아서 사용하는 추상클래스이다.

  - java.rmi.server.RMIClassLoader
   ClassLoader 가 아니며, RMI 런타임에서 클래스의 로딩과 마샬링을 처리해주는 래퍼클래스이다. 실제로sun.rmi.serer.LoaderHandler 와의 간단한 브릿지 역할을 하는 클래스이다. 실제 클래스 로딩은 LoaderHandler 의 Inner 클래스가 담당하게 된다. 이때 이 inner 클래스들은 URLClassLoader 를 상속받아 구현되어 있다.

* Custom ClassLoader 는 findClass(String) 를 구현하여 자신만의 클래스 로딩에만 신경쓰면 되며, 나머지는 parent 로 올리면 된다.
반응형
블로그 이미지

Good Joon

IT Professionalist Since 1999

,