Spec-Zone .ru
спецификации, руководства, описания, API
|
S
- Тип службы, которая будет загружена этим загрузчикомpublic final class ServiceLoader<S> extends Object implements Iterable<S>
Служба является известным набором интерфейсов и (обычно краткий обзор) классы. Поставщик услуг является определенной реализацией службы. Классы в провайдере обычно реализуют интерфейсы и разделяют на подклассы классы, определенные в службе непосредственно. Поставщики услуг могут быть установлены в реализации платформы Java в форме расширений, то есть, файлы фляги, помещенные в любой из обычных каталогов расширения. Провайдеры могут также быть сделаны доступными, добавляя их к пути к классу приложения или некоторыми другими специфичными для платформы средствами.
С целью загрузки служба представляется единственным типом, то есть, единственным интерфейсным или абстрактным классом. (Реальный класс может использоваться, но это не рекомендуется.) Провайдер данной службы содержит один или более реальные классы, которые расширяют этот тип службы с помощью данных и кодируют определенный для провайдера. Класс провайдера обычно является не всем провайдером непосредственно, а скорее прокси, который содержит достаточную информацию, чтобы решить, ли провайдер в состоянии удовлетворить определенный запрос вместе кодом, который может создать фактического провайдера по требованию. Детали классов провайдера имеют тенденцию быть очень специфичными для службы; никакой единый класс или интерфейс не могли возможно объединить их, таким образом, никакой такой тип не определяется здесь. Единственное требование, осуществленное этим средством, - то, что у классов провайдера должен быть конструктор нулевого параметра так, чтобы они можно было инстанцировать во время загрузки.
Поставщик услуг идентифицируется, помещая конфигурационный файл провайдера в каталоге META-INF/services ресурса. Имя файла является полностью определенным двоичным именем типа службы. Файл содержит список полностью определенных двоичных имен конкретных классов провайдера, один на строку. Пространство и символы вкладки, окружающие каждое имя, так же как пустые строки, игнорируются. Символом комментария является '#' ('\u0023', ЗНАК НОМЕРА); на каждой строке игнорируются все символы после первого символа комментария. Файл должен быть закодирован в UTF-8.
Если определенный конкретный класс провайдера называют больше чем в одном конфигурационном файле, или называется в том же самом конфигурационном файле не раз, то копии игнорируются. Конфигурационный файл, называя определенного провайдера не должен быть в том же самом файле фляги или другом модуле распределения как провайдер непосредственно. Провайдер должен быть доступным от того же самого загрузчика класса, который был первоначально запрошен, чтобы определить местоположение конфигурационного файла; отметьте, что это - не обязательно загрузчик класса, из которого был фактически загружен файл.
Провайдеры располагаются и инстанцируются лениво, то есть, по требованию. Загрузчик службы поддерживает кэш провайдеров, которые до сих пор загружались. Каждый вызов iterator
метод возвращает iterator, что первые урожаи все элементы кэша, в порядке инстанцирования, и затем лениво определяют местоположение и инстанцируют любых остающихся провайдеров, добавляя каждого к кэшу поочередно. Кэш может быть очищен через reload
метод.
Загрузчики службы всегда выполняются в контексте защиты вызывающей стороны. Код достоверной системы должен обычно вызывать методы в этом классе, и методы iterators, который они возвращают изнутри привилегированного контекста защиты.
Экземпляры этого класса не безопасны для использования многократными параллельными потоками.
Если иначе не определено, передавая параметр null любому методу в этом классе вызовет a NullPointerException
быть брошенным.
Пример Предполагает, что у нас есть тип службы com.example.CodecSet, который предназначается, чтобы представить наборы пар кодера/декодера для некоторого протокола. В этом случае это - абстрактный класс с двумя абстрактными методами:
Каждый метод возвращает соответствующий объект или null, если провайдер не поддерживает данное кодирование. Типичные провайдеры поддерживают больше чем одно кодирование.public abstract Encoder getEncoder(String encodingName); public abstract Decoder getDecoder(String encodingName);
Если com.example.impl.StandardCodecs является реализацией службы CodecSet тогда, ее файл фляги также содержит названный файл
META-INF/services/com.example.CodecSet
Этот файл содержит одну строку:
com.example.impl.StandardCodecs # Standard codecs
Класс CodecSet создает и сохраняет единственный экземпляр службы в инициализации:
private static ServiceLoader<CodecSet> codecSetLoader = ServiceLoader.load(CodecSet.class);
Чтобы определить местоположение кодера для данного кодирования имени, это определяет статический метод фабрики, который выполняет итерации через известных и доступных провайдеров, возвращаясь только, когда это определило местоположение подходящего кодера или исчерпало провайдеров.
public static Encoder getEncoder(String encodingName) { for (CodecSet cp : codecSetLoader) { Encoder enc = cp.getEncoder(encodingName); if (enc != null) return enc; } return null; }
Метод getDecoder определяется так же.
Примечание использования, Если путь к классу загрузчика класса, который используется для загрузки провайдера, включает удаленные сетевые URL тогда те URL, будет разыменовано в процессе поиска конфигурационных файлов провайдера.
Это действие нормально, хотя оно может заставить озадачивающие записи создаваться в журналах веб-сервера. Если веб-сервер не конфигурируется правильно, однако, то это действие может заставить загружающий провайдера алгоритм перестать работать побочно.
Веб-сервер должен возвратить HTTP 404 (Не Найденный) ответ, когда требуемый ресурс не существует. Иногда, однако, веб-серверы ошибочно конфигурируются, чтобы возвратить HTTP 200 (OK) ответ наряду с полезной ошибочной страницей HTML в таких случаях. Это вызовет a ServiceConfigurationError
быть брошенным, когда этот класс пытается проанализировать страницу HTML как конфигурационный файл провайдера. Лучшее решение этой проблемы состоит в том, чтобы фиксировать неправильно сконфигурированный веб-сервер, чтобы возвратить корректный код ответа (HTTP 404) наряду с ошибочной страницей HTML.
Модификатор и Тип | Метод и Описание |
---|---|
Iterator<S> |
iterator()
Лениво загружает доступных провайдеров службы этого загрузчика.
|
static <S> ServiceLoader<S> |
load(Class<S> service)
Создает новый загрузчик службы для данного типа службы, используя загрузчик класса контекста текущего потока.
|
static <S> ServiceLoader<S> |
load(Class<S> service, ClassLoader loader)
Создает новый загрузчик службы для данного типа службы и загрузчик класса.
|
static <S> ServiceLoader<S> |
loadInstalled(Class<S> service)
Создает новый загрузчик службы для данного типа службы, используя загрузчик класса расширения.
|
void |
reload()
Очистите кэш провайдера этого загрузчика так, чтобы все провайдеры были перезагружены.
|
Строка |
toString()
Возвращает строку, описывающую эту службу.
|
public void reload()
После вызова этого метода, последующих вызовов iterator
метод будет лениво искать и инстанцировать провайдеров с нуля, как делается недавно создаваемым загрузчиком.
Этот метод предназначается для использования в ситуациях, в которых новые провайдеры могут быть установлены в рабочую виртуальную машину Java.
public Iterator<S> iterator()
iterator, возвращенный этим методом первые урожаи все элементы кэша провайдера, в порядке инстанцирования. Это тогда лениво загружает и инстанцирует любых остающихся провайдеров, добавляя каждого к кэшу поочередно.
Чтобы достигнуть лени, фактическая работа парсинга доступных конфигурационных файлов провайдера и инстанцирования провайдеров должна быть сделана iterator непосредственно. hasNext
и next
методы могут поэтому бросить a ServiceConfigurationError
если конфигурационный файл провайдера нарушает указанный формат, или если это называет класс провайдера, который не может быть найден и инстанцирован, или если результат инстанцирования класса не присваиваем типу службы, или если какой-либо другой вид исключения или ошибки бросается, поскольку следующий провайдер располагается и инстанцируется. Чтобы записать устойчивый код, только необходимо поймать ServiceConfigurationError
при использовании службы iterator.
Если такая ошибка будет брошена тогда, то последующие вызовы iterator сделают максимальные усилия, чтобы определить местоположение и инстанцировать следующего доступного провайдера, но вообще такое восстановление не может быть гарантировано.
Примечание проекта, Бросающее ошибку в эти случаи, может казаться экстремальным значением. Объяснение для этого поведения - то, что уродливый конфигурационный файл провайдера, как уродливый файл класса, указывает на серьёзную проблему со способом, которым виртуальная машина Java конфигурируется или используется. Как таковой предпочтительно бросить ошибку, а не попытаться восстановиться или, еще хуже, перестать работать тихо.
iterator, возвращенный этим методом, не поддерживает удаление. Вызов remove
метод вызовет UnsupportedOperationException
быть брошенным.
public static <S> ServiceLoader<S> load(Class<S> service, ClassLoader loader)
service
- Интерфейсный или абстрактный класс, представляющий службуloader
- Загрузчик класса, который будет использоваться, чтобы загрузить конфигурационные файлы провайдера и классы провайдера, или null, если системный загрузчик класса (или, приводя к сбою это, загрузчик класса начальной загрузки) должен использоватьсяpublic static <S> ServiceLoader<S> load(Class<S> service)
Вызов этого метода удобства формы
эквивалентноServiceLoader.load(service)
ServiceLoader.load(service, Thread.currentThread().getContextClassLoader())
service
- Интерфейсный или абстрактный класс, представляющий службуpublic static <S> ServiceLoader<S> loadInstalled(Class<S> service)
Этот метод удобства просто определяет местоположение загрузчика класса расширения, вызовите это extClassLoader, и затем возвратитесь
ServiceLoader.load(service, extClassLoader)
Если загрузчик класса расширения не может быть найден тогда, системный загрузчик класса используется; если нет никакого системного загрузчика класса тогда, загрузчик класса начальной загрузки используется.
Этот метод предназначается для использования, когда только установленные провайдеры требуются. Получающаяся служба только найдет и загрузит провайдеров, которые были установлены в текущую виртуальную машину Java; провайдеры на пути к классу приложения будут проигнорированы.
service
- Интерфейсный или абстрактный класс, представляющий службу
Для дальнейшей ссылки API и документации разработчика, см.
Авторское право © 1993, 2011, Oracle и/или его филиалы. Все права защищены.