2016-12-12 2 views
2

Я изучаю процесс загрузки java-класса и сталкиваюсь с некоторой путаницей.Как узнать текущий классLoader в java

Я знаю, что при загрузке класса Java, текущего ClassLoader обыкновения загружать класс Java напрямую, и он будет передавать его родительского загрузчика (рекурсивный процесс), пока родитель наклоняет загрузить этот класс.


Вопрос заключается в том, что: , что текущий ClassLoader?Bootstrap? Расширение? Приложение?
Как получить текущий классLoader ?. , и я знаю, что есть API:

xxx.Class.getClassLoader(); 

, но я не уверен, что значение возвращение ли currentClassLoader. Я думаю, что это должен быть классLoader, который загружает этот класс java класс в реальность.

Чтобы описать мой вопрос более подробно, я приведу пример.
Я получаю содержание в блоге.

ThreadContextClassLoader используется для борьбы с Java SPI, интерфейс определен в Java core lib и загружен Bootstrap ClassLoader и третьей сторона реализацией этого интерфейса, то банка загружается AppClassLoader
Решение: традиционный classLoader не может справиться с этим делом, потому что он не может обнаружить стороннюю банку, когда мы используем стороннее внедрение в основной библиотеке.

большинство из вышесказанного, я могу понять, но решение сделать меня путаница: , например, интерфейс Corea и класс CoreB находятся в Java core lib и должен быть загружен Bootstrap ClassLoader а AImpl является орудием A третьей стороной и должен быть загружен Загрузчик AppClass.

сегмент кода, как показано ниже:

public Interface CoreA{ 
    void add(); 
} 

public Interface AImpl implements CoreA{ 
    void add(){}; 
} 

public class B{ 
     public void demo(){ 
     a = new AImpl(); 
     } 
} 

тогда, если мы ссылаемся B в main method, то мы будем загружать B потому что загрузчик классов из B является Bootstrap тогда о AImpl тока Загрузчик Bootstrap, так что его нельзя найти? Я не знаю, насколько я это понимаю?

Любые советы будут оценены.

+1

В разных средах используются разные стратегии загрузки классов. По умолчанию используется для первого распространения запроса загрузки класса на загрузчик родительского класса. Если он не может загрузить класс, этот загрузчик этого класса попытается загрузить его. Однако некоторые загрузчики классов сервера приложений не будут сначала запрашивать загрузчик родительского класса, если они могут загружать класс самостоятельно. Далее, в OSGi существует еще более сложная магия загрузчика классов для реализации модульной системы. –

+1

Нет такой вещи, как «текущий ClassLoader». Каждый класс загружается определенным ClassLoader. Вот и все. – VGR

+0

Иногда я сталкиваюсь с термином 'current classloader', и все в порядке, это просто' classloader' текущего исполняемого класса. – dmitrievanthony

ответ

0

«Текущий загрузчик классов» является реального Загрузчик классов (загрузить этот класс в действительности) класса, которые его называют.

например. если ClassLoader из class A является доб Загрузчик классов и class A см класс B C D. Затем «текущий загрузчик классов» B C D - ext classLoader. И, конечно, «текущий классLoader» основной класс - Системный классLoader.

1

Вообще говоря, вы точно правы, его не найти. Позвольте мне показать вам следующий пример. Скажем, у нас есть 3 класса: A, B и Основные как это:

public class A { 
    public String a() { 
     return "a"; 
    } 
} 

public class B { 
    public String b() { 
     return new A().a(); 
    } 
} 

public class Main { 
    public static void main(String... args) { 
     System.out.println(new B().b()); 
    } 
} 

И мы упаковываем эти классы в корреспондентские банки: a.jar, b.jar и поместить Main.class в рабочий каталог. После проверки этого Проследим сценария:

1) Все (класс A.class, B.class, Main.class) загружается system classloader и работает отлично:

# java -cp .:a.jar:b.jar Main 
a 

2) B.class загружается system classloader и класс A.class загружается bootstrap classloader и все еще работает нормально, потому что system classloader делегатов Загрузка в bootstrap classloader (только потому, что bootstrap classloader может загрузить его):

# java -Xbootclasspath/a:a.jar -cp .:b.jar Main 
a 

3) класс A.class загружается system classloader и B.class загружается bootstrap classloader (ваш случай). Он такой сценарий current classloader при загрузке B.class является bootstrap classloader, но он не может найден B.class и не:

# java -Xbootclasspath/a:b.jar -cp .:a.jar Main 
Exception in thread "main" java.lang.NoClassDefFoundError: A 
     at B.b(B.java:4) 
     at Main.main(Main.java:4) 

Давайте бабло на последний пример более тщательно. Что здесь происходит:

  1. Попробуйте найти класс с public static main(String[] args) методом

    1.1. system classloader еще не загружены, так что делегировать его extension classloader

    1.2. extension classloader еще не загружены, так что делегировать его bootstrap classloader

    1.3. bootstrap classloader не загрузил его и попытался загрузить, он не может его загрузить и возвращает управление extension classloader

    1.4. extension classloader попытаться загрузить, он не может загрузить его и возвращает управление на system classloader

    1.5. system classloader грузы Main.class

  2. Main.class обрабатывается, и мы пытаемся загрузить B.class с текущим загрузчиком классов system classloader

    2.1. system classloader еще не загружены, так что делегировать до extension classloader

    2.2. extension classloader еще не загружены, так что делегировать его bootstrap classloader

    2.3. bootstrap classloader не зарядил еще и загружает B.class

  3. B.class обрабатывается и, и мы пытаемся загрузить A.class с текущим загрузчиком классов bootstrap classloader

    3.1.bootstrap classloader не зарядил еще и пытается загрузить и терпит неудачу

Я надеюсь, что это поможет;)

+0

спасибо за ваш вклад. Это очень помогает мне. Но я думаю, что существует небольшой недостаток в ** разделе 2 ** ', потому что системный загрузчик классов загружает загрузочный загрузчик классов, если не может загрузить сам класс. _system classloader_ делегирует загрузку в _its родительский классLoader_ не является причиной того, что он сам не может загружать класс. Только если его _parent classloader_ не справляется с загрузкой java-класса, тогда _current class_ попытается загрузить сам класс. –

+0

Я обновил свой ответ и надеюсь, что сейчас это правильно. – dmitrievanthony

Смежные вопросы