Интервьюер: Вы понимаете модель родительского делегирования?

Java задняя часть Java EE
Интервьюер: Вы понимаете модель родительского делегирования?

интервьюер:Почему бы вам сегодня подробно не рассказать о механизме родительского делегирования?

Кандидат:хорошо.

Кандидат: Как упоминалось в прошлый раз: файлы классов загружаются в JVM через "загрузчик классов"

Кандидат: Чтобы предотвратить существование в памяти нескольких копий одного и того же байт-кода, используется механизм родительского делегирования (он не будет пытаться загрузить класс сам по себе, а делегирует запрос родительскому загрузчику для завершения, а затем идет вверх )

Кандидат: Классы собственных методов в JDK обычно загружаются корневым загрузчиком (загрузчиком Bootstrp), классы расширений, реализованные в JDK, обычно загружаются загрузчиком расширений (ExtClassLoader), а файлы классов в программе загружаются системой. загрузчик (AppClassLoader) Реализовать загрузку.

Кандидат: Это должно быть легко понять, верно?

интервьюер: Воробей ест (действительно)!

интервьюер:В продолжение темы хотелось бы спросить, что значит сломать механизм родительского делегирования?

Кандидат: Легко понять, это означает: пока я загружаю класс, я не ищу его в порядке APPClassLoader->Ext ClassLoader->BootStrap ClassLoader, тогда он сломан.

Кандидат: поскольку метод загрузки ядра класса находится в методе loadClass класса LoaderClass (основная реализация механизма родительского делегирования).

Кандидат: Затем, пока я настрою ClassLoader и перепишу метод loadClass (не начинайте искать загрузчик классов в соответствии с вышеизложенным), это будет считаться нарушением механизма родительского делегирования.

интервьюер:Так просто?

Кандидат: Ну, это так просто

интервьюер:Знаете ли вы сцену, в которой нарушается механизм родительского делегирования?

Кандидат: Самый очевидный из них — Tomcat.

интервьюер: Расскажите подробнее?

Кандидат: При развертывании проекта в начале мы помещаем пакет war под веб-приложение tomcat, что означает, что один tomcat может запускать несколько веб-приложений (:

Кандидат:правильно?

интервьюер: Эм..

Кандидат: Предположим, теперь у меня есть два веб-приложения, каждое из которых имеет класс с именем User, и оба имеют одно и то же полное имя класса, например com.yyy.User. Но их конкретная реализация отличается

Кандидат: Так как же Tomcat гарантирует, что они не будут конфликтовать?

Кандидат: Ответ заключается в том, что Tomcat создает экземпляр загрузчика классов (WebAppClassLoader) для каждого веб-приложения. Загрузчик переписывает метод loadClass и сначала загружает классы в текущий каталог приложения.

Кандидат: тогда достигается изоляция уровня веб-приложений.

интервьюер:Знаете ли вы, что у Tomcat есть и другие загрузчики классов?

Кандидат: ну я знаю

Кандидат: Не все зависимости под веб-приложением нужно изолировать.Например, Redis можно разделить между веб-приложениями (при необходимости), потому что если версия одинаковая, нет необходимости загружать отдельную копию для каждого веб-приложения. .

Кандидат: Подход тоже очень простой.Tomcat добавляет загрузчик родительского класса (SharedClassLoader) в WebAppClassLoader.Если сам WebAppClassLoader не загружается в определенный класс, то делегируйте SharedClassLoader для его загрузки.

Кандидат: (Это не что иное, как размещение классов, которые должны быть разделены между приложениями, в общий каталог)

интервьюер: Эм..

Кандидат: Чтобы изолировать веб-приложение от классов самого Tomcat, существует загрузчик классов (CatalinaClassLoader) для загрузки зависимостей самого Tomcat.

Кандидат: если собственные зависимости и веб-приложения Tomcat также необходимо использовать совместно, то имеется также загрузчик классов (CommonClassLoader) для загрузки и последующего совместного использования.

Кандидат: Каталог загрузки каждого загрузчика классов можно просмотреть в файле конфигурации catalina.properties tomcat.

Кандидат: Позвольте мне немного нарисовать диаграмму структуры загрузки классов Tomcat, иначе она будет немного абстрактной.

интервьюер: Ну да ладно, понимаю, немного интересно.

интервьюер:Кстати, хочу спросить, вы не знаете JDBC, я слышал, что он также разрушает модель родительского делегирования, как вы это понимаете.

Кандидат: Эмм, это вопрос мнения, сломано это или нет.

Кандидат: JDBC определяет интерфейс, а определенные классы реализации реализуются различными производителями (например, MySQL).

Кандидат: Существует правило для загрузки классов: если класс загружается загрузчиком классов А, то зависимые классы этого класса также загружаются "тем же самым загрузчиком классов".

Кандидат: Когда мы используем JDBC, мы используем DriverManager для получения Connection.DriverManager загружается загрузчиком классов BootStrap в пакете java.sql.

Кандидат: Когда мы используем DriverManager.getConnection(), мы должны получить класс, реализованный производителем.

Кандидат: Но сможет ли BootStrap ClassLoader загружать классы, реализованные разными производителями?

Кандидат: Очевидно нет, этих классов реализации нет в пакете java, как их можно загрузить?

интервьюер: Эм..

Кандидат: Решение для DriverManager состоит в том, чтобы получить «загрузчик контекста потока» при инициализации DriverManager.

Кандидат: при получении соединения «Загрузчик контекста потока» используется для загрузки соединения, а загрузчик контекста потока здесь на самом деле является App ClassLoader.

Кандидат: Таким образом, когда вы получаете Connection, вам все равно нужно сначала найти Ext ClassLoader и BootStrap ClassLoader, но эти два загрузчика не могут быть загружены и в конечном итоге будут загружены App ClassLoader.

интервьюер: Эм..

Кандидат: В этом случае некоторые люди думают, что механизм родительского делегирования разрушен, потому что он должен быть загружен BootStrap ClassLoader, но вы пришли к "Thread Context Loader" и изменили "Class Loader"

Кандидат: Некоторые люди думают, что механизм родительского делегирования не уничтожается, а заменяется на "загрузчик контекста потока" для загрузки классов, но они все равно следуют: "Поищите загрузчик родительского класса для загрузки по очереди, и только тогда, когда вы можете" не найдешь, сделай сам. загрузи». Что "принцип" не изменился.

интервьюер: Тогда я понимаю

Резюме этой статьи:

  • Необходимые знания:В JDK есть три загрузчика классов по умолчанию: AppClassLoader, Ext ClassLoader и BootStrap ClassLoader. Родительским загрузчиком AppClassLoader является Ext ClassLoader, а родительским загрузчиком Ext ClassLoader — BootStrap ClassLoader. Родительско-потомковые отношения здесь достигаются не наследованием, а композицией.

  • Что такое механизм родительского делегирования:В процессе загрузки загрузчика класс сначала передается загрузчику родительского класса для загрузки, и загрузчик родительского класса не обнаруживается до тех пор, пока не будет загружен сам.

  • Назначение механизма родительского делегирования:Чтобы предотвратить несколько копий одного и того же байт-кода в памяти (безопасность)

  • Правила загрузки класса:Если класс загружается загрузчиком классов A, то зависимые классы этого класса также загружаются «одним и тем же загрузчиком классов».

  • Как сломать механизм родительского делегирования:Настроить ClassLoader и переписать метод loadClass (до тех пор, пока он не будет передан родительскому загрузчику для загрузки по очереди, даже если механизм родительского делегирования не работает)

  • Примеры нарушения механизма родительского делегирования: Tomcat

    • Для изоляции классов веб-приложений создайте загрузчик классов WebAppClassLoader для каждого приложения.
    • Для совместного использования классов веб-приложений используйте ShareClassLoader в качестве загрузчика родительского класса для WebAppClassLoader. Если загрузчик WebAppClassLoader не может быть найден, попробуйте загрузить его с помощью ShareClassLoader.
    • Чтобы изолировать сам Tomcat от классов веб-приложений, используйте загрузчик классов CatalinaClassLoader для изоляции, а CatalinaClassLoader загружает собственные классы Tomcat.
    • Чтобы Tomcat мог совместно использовать классы с веб-приложениями, используйте CommonClassLoader в качестве загрузчика родительских классов для CatalinaClassLoader и ShareClassLoader.
    • Каталоги ShareClassLoader, CatalinaClassLoader и CommonClassLoader можно настроить в catalina.properties Tomcat.
  • Загрузчик контекста потока:Из-за правил загрузки классов очень вероятно, что родительский загрузчик зависит от классов дочернего загрузчика при загрузке, что приводит к невозможности успешной загрузки (BootStrap ClassLoader не может загружать классы сторонних библиотек), поэтому существует "загрузчик контекста потока" для загрузки.

Добро пожаловать в мой публичный аккаунт WeChat【Java3y] Давайте поговорим о Java-интервью, серия онлайн-интервьюеров постоянно обновляется!

Серия [Онлайн-интервьюер-Мобильный терминал]Продолжаем обновлять два раза в неделю!

【Онлайн-интервьюер-компьютер】СерияПродолжаем обновлять два раза в неделю!

Оригинал это не просто! ! Проси три! !