전공공부/JAVA

[JAVA] ClassLoader 란?

프로호구래머 2020. 9. 18. 15:55

해당 클래스로더에 대한 내용은 JAVA SE8 API에 명시된 내용이다. 다른 버전의 클래스로더에 대한 내용은 해당 버전의 API를 살펴보기를 추천한다.

 

클래스로더는 클래스들을 로딩시킬 책임이 있는 객체이다. 클래스로더 클래스는 추상클래스이다.
주어진 클래스의 바이너리 이름으로, 클래스로더는 클래스를 위한 정의를 대체하는 데이터를 위치하거나 만들어내는데 시도해야한다.
전형적인 전략은 그 이름(바이너리 이름인듯)을 파일이름으로 변환하고 파일시스템에서 그 이름으로된 클래스 파일을 읽는것이다.

모든 클래스 객체는 그 클래스를 정의한 클래스로더에 대한 래퍼런스를 포함한다.

배열 클래스를 위한 클래스 객체들은 클래스로더들에의해 만들어지지 않지만, 자바 런타임의 요구에의해 자동적으로 만들어진다.
Class.getClassLoader()에 의해 반환되는 배열 클래스를 위한 클래스 로더는 배열의 요소 타입의 클래스로더와 같다.
만약 요소 타입이 원시 타입이면 배열 클래스는 클래스로더를 가지지 않는다.

어플리케이션들은 JVM이 동적으로 클래스들을 로드하는 방식을 확장하기 위해서 클래스로드의 서브클래스들을 구현한다.

클래스로더들은 보안 도메인들은 나타내기 위해서 보안 관리자들에의해 사용될 수도 있다.

클래스로더 클래스는 클래스와 자원들을 검색하기 위해 위임모델을 사용한다. 각 클래스로더의 인스턴스는 연관된 부모 클래스 로더를 가진다. 클래스나 자원을 찾도록 요구되었을 때, 클래스로더 인스턴스는 자기자신이 클래스와 자원을 찾기전에 부모 클래스로더에게 클래스와 자원을 찾도록 위임할 것이다. 부트스트랩 클래스 로더라 불리는 가상머신의 built-in 클래스로더는 자신의 부모를 가지지 않고 클래스로더 인스턴스의 부모로 다뤄진다. 

클래스들의 동시 로딩을 지원하는 클래스로더들은 parallel capable class로 알려져 있고 그들은 그들의 클래스 초기화 시간에 ClassLoader.registerAsParallelCapable method를 호출해서 그들 스스로를 등록하도록 요구된다.
클래스로더 클래스는 디폴트로 parallel capable로 등록된다는 것을 명심하라.
하지만, 그것의 하위클래스들은 여전히 그들이 parallel capable이라면 스스로 등록할 필요가 있다.
엄격한 계층형이 아닌 위임모델 환경에서는 클래스로더들은 parallel capable일 필요가 있는 반면, 클래스 로딩이 데드락을 초래할 수 있다. 왜냐면 클래스 로딩 과정동안 로더락이 걸릴수도 있기 때문이다.

보통, JVM은 로컬 파일 시스템으로부터 플랫폼 종속적인 방식으로 클래스들을 로드한다. 예로, 유닉스 시스템에서 가상머신은 클래스들을 CLASSPATH 환경 변수에 정의된 폴더로부터 로드한다.

하지만, 몇몇 클래스들은 파일로부터 유래하지않을수도 있다. 그들은 네트워크와 같은 다른소스들로부터 유래될 수도 있고 어플리케이션에의해 구성될수도 있다.
defineClass method는 바이트 배열을 Class 클래스로 변환한다.
새로 정의된 클래스의 인스턴스는 Class.newInstance로 만들어 질수 있다.

클래스로더로 만들어진 객체들의 메소드와 생성자들은 다른 클래스들은 참조할수도 있다.
언급된 클래스들을 결정하기 위해서, JVM은 그 클래스들을 본래 만들었던 클래스로더의 loadClass method를 호출한다.

예로, 어플리케이션은 서버로부터 클래스파일들을 다운받기 위해서 네트워크 클래스로더를 만들수 있다. 샘플코드는 이렇다:
ClassLoader loader = new NetworkclassLoader(host, port);
Object main = loader.loadClass("Main", true).newInstance();

그 네트워크 클래스로더 하위클래스는 네트워크로부터 클래스를 로드하기 위해서 findClass와 loadClassData method를 정의해야만 한다. 일단 클래스를 만드는 바이트들을 다운받으면, 클래스 인스턴스를 만들기위해 defineClass method를 사용해야만 한다. 샘플 구현은 :
class NetworkClassLoader extends ClassLoader {
  String host;
  int port;

  public Class findClass(String name) {
    byte[] b = loadClassData(name);
    return defineClass(name, b, 0, b.length);
  }

  private byte[] loadClassData(String name) {
    //load the class data from the connection
    ''''
  }
}

 

우선은 여러 곳에서 클래스로더에 대한 내용을 많이 알아보았는데 내공이 부족한 나에게는 완벽하게 이해가 되지 않아서 java api를 해석해보았다. 좀더 해석한 것을 곱씹어보아야겠다..

 

classLoader를 완벽히 이해하기 위해서는 SOLID의 위임법칙, JVM구조와 동작원리 등에 대한 공부도 필요한것같다..

 

javacan.tistory.com/entry/1

해당 블로그도 참고해보자!


출처

https://docs.oracle.com/javase/8/docs/api/java/lang/ClassLoader.html

 

ClassLoader (Java Platform SE 8 )

Converts a ByteBuffer into an instance of class Class, with an optional ProtectionDomain. If the domain is null, then a default domain will be assigned to the class as specified in the documentation for defineClass(String, byte[], int, int). Before the cla

docs.oracle.com

 

 

'전공공부 > JAVA' 카테고리의 다른 글

Arrays.sort() 오름차순 내림차순  (0) 2020.10.12
[JAVA] Comparable과 Comparator의 차이점  (0) 2020.10.07
[JAVA] Math.pow() 를 이용한 거듭제곱  (0) 2020.10.07
java string 비교  (0) 2020.08.28
Class.forName()의 동작원리  (0) 2020.08.11