[독서 노트] Java 클래스 로더

24121 단어

클래스 및 클래스 캐리어


클래스 마운트는 클래스 마운트 단계의 역할을 제외하고 하나의 클래스에 대해 클래스 마운트를 하는 클래스 마운트와 이 클래스 자체가 자바 가상 기기의 유일성을 함께 확정해야 한다.통속적으로 말하자면 두 종류가'상등'인지 아닌지를 판단하려면 전제는 이 두 종류는 반드시 같은 종류의 캐리어에 불러와야 한다. 그렇지 않으면 이 두 종류는'상등하지 않다'는 것이다.여기서 가리키는'상등'은 클래스의 클라스 대상의 equals() 방법, isAssignableFrom() 방법, isInstance() 방법, instanceof 키워드 등을 포함하여 판단한 결과이다.예: 서로 다른 클래스 마운트가 instanceof 키워드 결과에 미치는 영향

  
  
  
  
  1. package org.kesar;
  2. import java.io.IOException;
  3. import java.io.InputStream;
  4. public class ClassLoaderTest
  5. {
  6. /**
  7. * @param args
  8. * @throws Exception
  9. */
  10. public static void main(String[] args) throws Exception
  11. {
  12. ClassLoader myLoader = new ClassLoader()
  13. {
  14. @Override
  15. public Class<?> loadClass(String name)
  16. throws ClassNotFoundException
  17. {
  18. try
  19. {
  20. String fileName = name.substring(name.lastIndexOf(".") + 1) + ".class";
  21. InputStream is = getClass().getResourceAsStream(fileName);
  22. if (is == null)
  23. {
  24. return super.loadClass(name);
  25. }
  26. byte[] b = new byte[is.available()];
  27. is.read(b);
  28. return defineClass(name, b, 0, b.length);
  29. }
  30. catch (IOException e)
  31. {
  32. throw new ClassNotFoundException(name);
  33. }
  34. }
  35. };
  36. Object obj=myLoader.loadClass("org.kesar.ClassLoaderTest").newInstance();
  37. System.out.println(obj.getClass());
  38. System.out.println(obj instanceof ClassLoaderTest);
  39. }
  40. }


class org.kesar.ClassLoaderTest
false


ClassLoaderTest , , , “ ”。

2. 양친위 파견 모델

Java , 。 (Bootstrap ClassLoader), ; , , java.lang.ClassLoader . 시스템에서 제공하는 클래스 마운트에 대해 말하자면, 이 세 종류의 마운트가 있다. 부팅 클래스 마운트, 확장 클래스 마운트, 응용 프로그램 클래스 마운트이다.

1. 시스템의 클래스 로더


(1) 부팅 클래스 로더(Bootstrap ClassLoader) 로딩 내용: <JAVA_HOME>\lib 디렉터리, -Xbootclasspath 매개 변수가 지정한 경로에 있는 가상 기기가 식별할 수 있는 클래스 라이브러리가 가상 기기 메모리에 로딩됩니다.특징: 자바 프로그램에서 직접 인용할 수 없습니다. 마운트 의뢰를 시작 클래스 마운트에 불러오려면 null로 대체하면 됩니다.
예: java.lang.Class의 getClassLoader () 소스

  
  
  
  
  1. /**
  2. * Returns the class loader for the class. Some implementations may use
  3. * null to represent the bootstrap class loader. This method will return
  4. * null in such implementations if this class was loaded by the bootstrap
  5. * class loader.
  6. */
  7. public ClassLoader getClassLoader() {
  8. ClassLoader cl = getClassLoader0();
  9. if (cl == null)
  10. return null;
  11. SecurityManager sm = System.getSecurityManager();
  12. if (sm != null) {
  13. ClassLoader.checkClassLoaderPermission(cl, Reflection.getCallerClass());
  14. }
  15. return cl;
  16. }

(2) 확장 클래스 로더(Extension ClassLoader) 로딩 내용: <JAVA_HOME>\lib\ext 디렉터리, java.ext.dirs 시스템 변수에 의해 지정된 경로의 모든 클래스 라이브러리 특징: 자바 컴파일링을 사용하여 개발자가 확장 클래스 로더를 직접 사용할 수 있음
(3) 응용 프로그램 클래스 로더(Application ClassLoader) 로딩 내용: 사용자 클래스 경로(ClassPath)에 지정된 클래스 라이브러리 특징을 로딩합니다. 개발자는 이 클래스 로더를 직접 사용할 수 있습니다. 사용자 정의 클래스 로더가 없으면 기본적으로 사용할 수 있습니다.

2. 부모 위임 모델(Parents Delegation Model)


작업 과정: 클래스 로더가 클래스 로더 요청을 받았을 때 클래스를 직접 로드하지 않습니다. 이 클래스 로더 요청은 상위 클래스 로더에 위임됩니다. 각 단계의 클래스 로더는 이렇게 합니다. 이 클래스가 상위 클래스가 없을 때(Bootstrap ClassLoader) 또는 상위 클래스 로더의 피드백이 이 클래스를 로드할 수 없을 때(검색 범위에서 필요한 클래스를 찾지 못했을 때)서브 캐리어가 스스로 불러옵니다.
클래스의 부모 위임 모델은 다음과 같다.
장점: 양친위 파견 모델을 사용하면 작업 과정의 특징으로 인해 자바 클래스는 클래스 로더와 함께 우선순위가 있는 차원 관계를 가지게 된다(차원이 높을수록 우선순위가 있다).예를 들어 java.lang.Object은 모든 클래스가 기본적으로 이 클래스를 계승하기 때문에 매번 클래스가 불러올 때마다 이 클래스를 불러온다. 이 클래스는 rt.jar에 존재하고 부모위 파견 모델을 사용하면 매번 클래스 가치 요청은 시작 클래스 캐리어에 위임되기 때문에 java.lang.Object에 성공적으로 불러올 수 있다.그리고 java.lang.Object의 매번 위임은 부팅 클래스 마운트에 의해 불러오기 때문에 클래스가 가상 기기에서의 일치성을 확보한다.만약 이러한 메커니즘을 잃게 된다면, 모든 클래스 마운트는 자신을 java.lang.Object으로 불러올 것이다. 그러면 시스템에 서로 다른 Object클래스가 여러 개 있을 것이고, 응용 프로그램은 혼란스러울 것이다.
ClassLoader의 loadClass() 메소드 소스를 볼 수 있습니다.

  
  
  
  
  1. protected Class<?> loadClass(String name, boolean resolve)
  2. throws ClassNotFoundException
  3. {
  4. synchronized (getClassLoadingLock(name)) {
  5. // ,
  6. Class c = findLoadedClass(name);
  7. if (c == null) {
  8. long t0 = System.nanoTime();
  9. try {
  10. if (parent != null) {
  11. c = parent.loadClass(name, false);
  12. } else {
  13. c = findBootstrapClassOrNull(name);
  14. }
  15. } catch (ClassNotFoundException e) {
  16. // ClassNotFoundException
  17. //
  18. }
  19. if (c == null) {
  20. // ,
  21. long t1 = System.nanoTime();
  22. c = findClass(name);
  23. // this is the defining class loader; record the stats
  24. sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
  25. sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
  26. sun.misc.PerfCounter.getFindClasses().increment();
  27. }
  28. }
  29. if (resolve) {
  30. resolveClass(c);
  31. }
  32. return c;
  33. }
  34. }

3. 부모위 파견 모형 세 차례 파괴

(1) :JDK
:JDK1.2 。JDK1.0 ClassLoader , , ClassLoader findClass() 。 , findClass() 。
:JDK1.2 , ClassLoader loadClass() , loadClass() , findClass() 。

(2) :
: 。 JNDI ,JNDI Java , , ClassPath JNDI , “ ” 。
: (Thread Context ClassLoader), , , 。

(3) :“ ”
: : 、 。
: Java OSGI, , , 。

:OSGI
1) java.* 。
2) , 。
3) , Import Export Bundle 。
4) , Bundle ClassPath, 。
5) , Fragment Bundle , , Fragment Bundle 。
6) , Dynamic Import Bundle, Bundle 。
7) , 。



(Wiz)


좋은 웹페이지 즐겨찾기