Загрузчики классов Java

Может ли кто-нибудь указать мне хороший ресурс или объяснить мне концепцию загрузчиков классов? Я нашел следующий ресурс по загрузчикам классов http://www.onjava.com/lpt/a/5586 но все равно не помогает. Следующие вопросы могут показаться глупыми, но попытки ответить на них всегда приводят меня в замешательство.

  • Почему разработчики пишут пользовательские загрузчики классов, почему бы не вызывать загрузчик классов Bootstrap для вызова ваших пользовательских классов? Какая необходимость в определении пользовательских загрузчиков классов?

  • Почему существует так много разновидностей загрузчиков классов? например: Bootsrap, Comman, загрузчик классов Catalina и т. д.,

    Заранее спасибо.


person BlueGene    schedule 12.02.2009    source источник


Ответы (8)


Я нашел следующие веские причины для создания пользовательских загрузчиков классов:

  1. Вы хотите загрузить класс из нетрадиционного источника (например, байт-код для одного класса хранится в базе данных, в сети или переносится голубями как 0 и 1 - MessengerPidgeonClassLoader). Для таких случаев в API уже есть некоторые реализации ClassLoader, например URLClassLoader.

  2. Вам нужно определить другую иерархию для загрузки классов. Реализации ClassLoader по умолчанию делегируют поиск сначала родителю, затем они пытаются загрузить класс сами. Может быть, вы хотите другую иерархию. Это причина, по которой OSGI и Eclipse имеют свои собственные загрузчики классов, поскольку файлы манифеста .MF определяют все типы странных путей иерархии (например, загрузка классов друзей). Все загрузчики классов Eclipse реализуют интерфейс BundleClassLoader и имеют дополнительный код для поиска ресурсов в подключаемых модулях Eclipse.

  3. Вам нужно внести некоторые изменения в байт-код. Возможно, байт-код зашифрован, и вы расшифруете его на лету (Не то, чтобы это действительно помогало, но было испробовано). Возможно, вы хотите «исправить» классы, загруженные на лету (улучшение байт-кода A la JDO).

Использование загрузчика классов, отличного от системного загрузчика классов, требуется, если вам нужно выгрузить классы из памяти или загрузить классы, определение которых может измениться во время выполнения. Типичным случаем является приложение, которое создает класс на лету, например, из XML-файла, а затем пытается перезагрузить этот класс. Как только класс находится в системном загрузчике классов, его невозможно выгрузить и получить новое определение.

person Mario Ortegón    schedule 12.02.2009
comment
хороший ответ, но голуби гарантируют плюс 1 :) - person ShuggyCoUk; 15.02.2009
comment
IP-дейтаграммы на авиационных носителях — лучший RFC из когда-либо существовавших :) И знаете что, он также был протестирован в реальной жизни! notes.co.il/benbasat/5240.asp - person Esko; 15.02.2009
comment
Поскольку вопрос закрыт, я добавлю комментарий, касающийся вашего пункта 3: Классы горячей замены во время первых раундов тестирования - очень актуально, если время перезапуска системы велико и находится вне вашего непосредственного влияния. Может быть сделано с соответствующей осторожностью - хотя, конечно, в целом не подходит для производственных систем. - person nsandersen; 07.11.2018

Обычно загрузчики классов используются для изоляции JAR. Если у вас есть приложение, использующее подключаемые модули (Eclipse, Maven 2), то у вас может быть такая ситуация: плагину X требуется jar A версии 1.0, а плагину Y нужен тот же jar, но версии 2.0. Однако X не работает с версией 2.0.

Если у вас есть загрузчики классов, вы можете создавать разделы классов (подумайте об изолированных островах, соединенных тонкими мостами; мосты — это загрузчики классов). Таким образом, загрузчики классов могут контролировать то, что может видеть каждый плагин.

Когда плагин X создает экземпляр класса Foo, который имеет статические поля, это не проблема, и не будет путаницы с «тем же самым» классом в плагине Y, потому что каждый загрузчик классов фактически создаст свой собственный экземпляр класса Foo. Затем у вас есть два класса в памяти, где cl1.getName().equals(cl2.getName()) равен true, а cl1.equals(cl2) — нет. Это означает, что экземпляры cl1 несовместимы по присваиванию с экземплярами cl2. Это может привести к странным ClassCastExceptions, которые говорят, что org.project.Foo не может быть назначено org.project.Foo.

Как и в случае с удаленными островами, два класса не знают о существовании другого. Подумайте о человеческих клонах, которые рождаются, а затем вырастают на разных островах. С точки зрения ВМ проблем нет, потому что экземпляры типа Class обрабатываются как любой другой объект: их может быть несколько. То, что вы думаете, что некоторые из них «одинаковые», не имеет значения для ВМ.

Другое использование этого шаблона заключается в том, что вы можете избавиться от классов, загруженных таким образом: просто убедитесь, что ни у кого нет указателя на какой-либо объект, созданный из классов, загруженных из загрузчика классов, а затем забудьте о загрузчике классов. При следующем запуске GC все классы, загруженные этим загрузчиком классов, удаляются из памяти. . Это позволяет вам «перезагрузить» ваше приложение без перезапуска всей виртуальной машины.

person Aaron Digulla    schedule 12.02.2009
comment
Хорошая аналогия, островная! +1 - person Mario Ortegón; 12.02.2009

Еще одна хорошая ссылка на загрузчики классов Java — загрузчики классов Java.

person harshit    schedule 17.04.2009

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

person Alex Miller    schedule 12.02.2009

В таких случаях вы не можете пройти мимо необработанного источника. Если вам действительно нужна внутренняя дурь, жесткое ядро, прочтите соответствующие части спецификации виртуальной машины Java.

person paulmurray    schedule 15.02.2009

Крайне редко вам нужно создать свой собственный ClassLoader. И вообще, если вам нужно, вы уже должны хорошо понимать, что делает ClassLoader.

Другими словами, если вы спрашиваете, зачем вам нужно создавать свой собственный ClassLoader, то вам не нужно его создавать ;)

При этом я также видел, как ClassLoader создавался для приложения, которое имело дело с криптографией. Таким образом, каждый раз, когда вы создаете java.netSocket или какой-либо объект файла/потока, вместо использования версий JVM он будет использовать свои собственные специальные настраиваемые классы. Таким образом, они могли гарантировать, что вся информация была зашифрована и что не было ошибок разработчиков.

Но это не очень распространено. Вы можете пройти всю карьеру Java, даже не создавая свой собственный ClassLoader. На самом деле, если вам нужно создать его, вы должны действительно спросить, необходимо ли это.

person Stephane Grenier    schedule 12.02.2009

Пример:

Tomcat использует настраиваемый загрузчик WebAppClassloader для загрузки и изоляции классов/jar-файлов из разных веб-приложений.

person acala    schedule 20.10.2016

Почему разработчики пишут пользовательские загрузчики классов, почему бы не использовать загрузчик классов Bootstrap для вызова ваших пользовательских классов? Зачем нужно определять пользовательские загрузчики классов?

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

Например, я использовал одно приложение, классы которого загружаются из LDAP :S

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

Что касается ресурсов, то их в сети ТОННЫ, которые просто невозможно перечислить.

person OscarRyz    schedule 12.02.2009