![]() |
Модераторы: LSD, AntonSaburov |
![]() ![]() ![]() |
|
LSD |
|
||||||||||||||
![]() Leprechaun Software Developer ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 15718 Регистрация: 24.3.2004 Где: Dublin Репутация: 210 Всего: 538 |
Механизм динамической загрузки классов – одна из основных причин по которой платформа Java приобрела значительную популярность. Загрузчики классов (classloaders) как раз и обеспечивают возможность расширения. Стандартный загрузчик java-машины используется для загрузки классов из каталогов или zip-архивов (правда, обычно имеющих расширение *.jar), определенных в системном свойстве java.class.path, содержимое которого определяется с помощью системной переменной CLASSPATH или установки ключа -cp при запуске java-машины.
Задача создания собственного загрузчика классов возникает довольно часто. Стоит отметить, что собственные загрузчики классов используют все серверы приложений м web-контейнеры, что и понятно – приложения, разворачиваемые на сервере приложений, должны загружаться динамически, в противном случае перечисление в переменной CLASSPATH всех библиотек, используемых приложениями, становится задачей нетривиальной. Скажу больше, серверы приложений, как правило, используют не один загрузчик классов, а целую их иерархию. Если проанализировать какие загрузчики используют компоненты EJB и сервлеты, то, скорее всего, окажется, что они совершенно разные. Собственный загрузчик классов использует Jakarta Ant и множество других приложений, библиотек и серверов. Ну хорошо, скажете вы, а мне-то это зачем? Необходимость в собственном загрузчике классов возникает достаточно часто в следующих случаях:
Что делать, если библиотеки доступны только удаленно, например, находятся на веб-сервере? Написать собственный загрузчик? На самом деле, в этом нет необходимости. Класс java.net.URLClassLoader, подклассом которого является стандартный загрузчик JVM, позволяет загружать классы не только из ресурсов, находящихся в файловой системе, но и из ресурсов, находящихся в сети, задавая URL. Однако, встречаются такие ситуации, когда и его возможностей недостаточно. При загрузке классов платформа Java использует механизм делегирования. Основная идея заключается в том, что каждый загрузчик классов имеет «родительский» загрузчик. В процессе загрузки классов загрузчик в первую очередь делегирует задачу поиска родительскому объекту-загрузчику прежде чем пытаться самому найти класс. При разработке загрузчика класса необходимо соблюдать этот принцип. Итак, поставим себе следующую задачу. Необходимо реализовать загрузчик, который может расширяться динамически, то есть в процессе работы приложения добавлять или удалять элементы CLASSPATH. Любой используемый в JVM загрузчик должен расширять java.lang.ClassLoader и переопределить в нем методы findClass() и findResource() (второй только в том случае если есть необходимость загружать не только классы, но и ресурсы).
Здесь атрибут cache будет использоваться для хранения уже найденных классов (не искать же их в самом деле при каждом обращении), paths – список путей поиска классов, включающий в себя каталоги и библиотеки, currentLoader будет хранить ссылку на дефолтный загрузчик классов.
Прежде чем искать класс в путях, зарегистрированных внутри загрузчика, пытаемся найти класс сначала в кэше классов, затем в стандартном загрузчике и только если класс найти не удается загрузчик сам пытается найти класс в заданных путях. Поиск класса выполняется в методе getClassFromAddedClassPaths(). Результатом работы этого метода должен быть массив байтов, представляющий нужный класс. Из массива байтов создается объект типа java.lang.Class, для чего можно использовать метод defineClass(), который реализован в java.lang.ClassLoader.
Теперь переопределим метод findResource(), предназначенный для поиска ресурсов. В отличие от findClass() он возвращает объекта класса java.net.URL.
Ну и, наконец, реализуем набор методов, которые позволяли бы изменять список путей, в которых хранятся классы.
Часто возникает необходимость сделать свой загрузчик классов дефолтным, поэтому неплохо было предусмотреть метод, позволяющий это сделать.
В атрибуте currentLoader сохраняем ссылку на текущий дефолтный загрузчик поскольку классы нужно будет искать не только в зарегистрированных нами ресурсах, но и в стандартном CLASSPATH. Теперь проверим как работает вся конструкция.
Если путь к библиотеке указан правильно, все должно выполниться безо всяких сообщений. В противном случае программа выдаст исключение java.lang.ClassNotFoundException. -------------------- Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it. |
||||||||||||||
|
|||||||||||||||
![]() ![]() ![]() |
Правила форума "Java" | |
|
Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Java: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |