Spec-Zone.ru › OpenJDK 25

Класс ServiceLoader<S>

java.lang.Object
java.util.ServiceLoader<S>
Параметры типа:
S — тип службы, загружаемой этим загрузчиком
Все реализуемые интерфейсы:
Iterable<S>
public final class ServiceLoader<S> extends Object implements Iterable<S>
Средство для загрузки реализаций службы.

Служба — это широко известный интерфейс или класс, для которого существует ноль, один или несколько поставщиков служб. Поставщик службы (или просто поставщик) — это класс, реализующий широко известный интерфейс или являющийся его подклассом. ServiceLoader — это объект, который находит и загружает поставщиков служб, развернутых в среде выполнения, в момент, выбранный приложением. Код приложения ссылается только на службу, а не на поставщиков служб, и предполагается, что он может выбрать одного из нескольких поставщиков служб (на основе предоставляемых ими через службу возможностей) и обработать ситуацию, когда поставщики служб не найдены.

Получение загрузчика служб

Приложение получает загрузчик служб для заданной службы, вызывая один из статических методов load класса ServiceLoader. Если приложение является модулем, его объявление модуля должно содержать директиву uses, указывающую службу; это помогает находить поставщиков и обеспечивает их надежное выполнение. Кроме того, если модуль приложения не содержит службу, его объявление модуля должно содержать директиву requires, указывающую модуль, экспортирующий службу. Настоятельно рекомендуется, чтобы модуль приложения не требовал модули, содержащие поставщиков службы.

Загрузчик служб можно использовать для поиска и создания экземпляров поставщиков службы с помощью метода iterator. ServiceLoader также определяет метод stream, возвращающий поток поставщиков, которые можно проверять и фильтровать, не создавая их экземпляры.

Например, предположим, что служба — это com.example.CodecFactory, интерфейс, определяющий методы для создания кодировщиков и декодеров:

    package com.example;
    public interface CodecFactory {
        Encoder getEncoder(String encodingName);
        Decoder getDecoder(String encodingName);
    }

Следующий код получает загрузчик служб для службы CodecFactory, а затем использует его итератор (автоматически создаваемый расширенным циклом for) для получения экземпляров найденных поставщиков службы:

    ServiceLoader<CodecFactory> loader = ServiceLoader.load(CodecFactory.class);
    for (CodecFactory factory : loader) {
        Encoder enc = factory.getEncoder("PNG");
        if (enc != null)
            ... use enc to encode a PNG file
            break;
        }

Если этот код находится в модуле, то для ссылки на интерфейс com.example.CodecFactory объявление модуля должно требовать модуль, экспортирующий этот интерфейс. В объявлении модуля также необходимо указать использование com.example.CodecFactory:

    requires com.example.codec.core;
    uses com.example.CodecFactory;

Иногда приложение может захотеть проверить поставщика службы до создания его экземпляра, чтобы определить, будет ли полезен экземпляр этого поставщика. Например, поставщик службы CodecFactory, способный создавать кодировщик «PNG», может быть аннотирован с помощью @PNG. В следующем коде используется метод stream загрузчика служб, чтобы получить экземпляры Provider<CodecFactory>, в отличие от итератора, который возвращает экземпляры CodecFactory:

    ServiceLoader<CodecFactory> loader = ServiceLoader.load(CodecFactory.class);
    Set<CodecFactory> pngFactories = loader
           .stream()                                              // Note a below
           .filter(p -> p.type().isAnnotationPresent(PNG.class))  // Note b
           .map(Provider::get)                                    // Note c
           .collect(Collectors.toSet());
  1. Поток объектов Provider<CodecFactory>
  2. p.type() возвращает Class<CodecFactory>
  3. get() возвращает экземпляр CodecFactory

Проектирование служб

Служба — это один тип, обычно интерфейс или абстрактный класс. Можно использовать конкретный класс, но это не рекомендуется. Тип может иметь любой уровень доступности. Методы службы в значительной степени зависят от предметной области, поэтому в этой спецификации API невозможно дать конкретные рекомендации относительно их формы или назначения. Однако можно сформулировать два общих правила:

  1. Служба должна объявлять столько методов, сколько необходимо, чтобы поставщики служб могли сообщать о своих свойствах, специфичных для предметной области, и других характеристиках качества реализации. Приложение, получившее загрузчик служб для этой службы, может вызывать эти методы для каждого экземпляра поставщика службы, чтобы выбрать наиболее подходящего поставщика.

  2. Служба должна указывать, должны ли ее поставщики быть непосредственными реализациями службы или использовать механизм косвенного обращения, например «прокси» или «фабрику». Поставщики служб, как правило, используют механизм косвенного обращения, если создание объектов предметной области обходится относительно дорого; в этом случае службу следует проектировать так, чтобы поставщики служб были абстракциями, создающими «реальную» реализацию по запросу. Например, служба CodecFactory своим названием указывает, что ее поставщики служб являются фабриками кодеков, а не самими кодеками, поскольку создание некоторых кодеков может быть дорогостоящим или сложным.

Разработка поставщиков служб

Поставщик службы — это один тип, обычно конкретный класс. Допускается интерфейс или абстрактный класс, поскольку он может объявлять статический метод поставщика, описанный далее. Тип должен быть открытым и не должен быть внутренним классом.

Поставщик службы и поддерживающий его код могут разрабатываться в модуле, который затем развертывается в пути модулей приложения или в модульном образе. В качестве альтернативы поставщик службы и поддерживающий его код можно упаковать в JAR-файл и развернуть в пути классов приложения. Преимущество разработки поставщика службы в модуле заключается в том, что поставщика можно полностью инкапсулировать, скрыв все детали его реализации.

Приложению, получающему загрузчик служб для заданной службы, неважно, развернуты ли поставщики службы в модулях или упакованы в JAR-файлы. Приложение создает экземпляры поставщиков служб с помощью итератора загрузчика служб или объектов Provider в потоке загрузчика служб, не зная расположения поставщиков служб.

Развертывание поставщиков служб в виде модулей

Поставщик службы, разработанный в модуле, должен быть указан в директиве provides объявления модуля. Директива provides указывает и службу, и поставщика службы; это помогает найти поставщика, когда другой модуль с директивой uses для этой службы получает загрузчик служб. Настоятельно рекомендуется не экспортировать пакет, содержащий поставщика службы. Модуль не может указывать в директиве provides поставщика службы, находящегося в другом модуле.

Поставщик службы, разработанный в модуле, не может контролировать момент создания своего экземпляра, поскольку это происходит по требованию приложения, но он может контролировать способ создания экземпляра:

  • Если поставщик службы объявляет метод поставщика, загрузчик служб вызывает этот метод для получения экземпляра поставщика службы. Метод поставщика — это открытый статический метод с именем "provider", без формальных параметров и с типом возвращаемого значения, присваиваемым интерфейсу или классу службы.

    В этом случае сам поставщик службы не обязан быть присваиваемым интерфейсу или классу службы.

  • Если поставщик службы не объявляет метод поставщика, экземпляр поставщика службы создается напрямую с помощью конструктора поставщика. Конструктор поставщика — это открытый конструктор без формальных параметров.

    В этом случае поставщик службы должен быть присваиваемым интерфейсу или классу службы.

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

Например, предположим, что модуль задает следующую директиву:

    provides com.example.CodecFactory with com.example.impl.StandardCodecs,
             com.example.impl.ExtendedCodecsFactory;

где

  • com.example.CodecFactory — описанная ранее служба с двумя методами.
  • com.example.impl.StandardCodecs — открытый класс, реализующий CodecFactory и имеющий открытый конструктор без аргументов.
  • com.example.impl.ExtendedCodecsFactory — открытый класс, не реализующий CodecFactory, но объявляющий открытый статический метод без аргументов с именем "provider" и типом возвращаемого значения CodecFactory.

Загрузчик служб создаст экземпляр StandardCodecs с помощью его конструктора, а экземпляр ExtendedCodecsFactory — вызвав его метод provider. Требование, согласно которому конструктор или метод поставщика должен быть открытым, помогает обозначить намерение: класс (то есть поставщик службы) будет создавать объект (то есть загрузчик служб), находящийся вне пакета класса.

Развертывание поставщиков служб в пути классов

Поставщик службы, упакованный в JAR-файл для пути классов, определяется путем размещения файла конфигурации поставщика в каталоге ресурсов META-INF/services. Имя файла конфигурации поставщика — это полное двоичное имя службы. Файл конфигурации поставщика содержит список полных двоичных имен поставщиков служб, по одному на строку.

Например, предположим, что поставщик службы com.example.impl.StandardCodecs упакован в JAR-файл для пути классов. JAR-файл будет содержать файл конфигурации поставщика с именем:

META-INF/services/com.example.CodecFactory
содержащий строку:
com.example.impl.StandardCodecs # Standard codecs

Файл конфигурации поставщика должен быть закодирован в UTF-8. Пробелы и символы табуляции вокруг имени каждого поставщика службы, а также пустые строки игнорируются. Символ комментария — '#' (U+0023 ЗНАК НОМЕРА); в каждой строке игнорируются все символы после первого символа комментария. Если имя класса поставщика службы указано в файле конфигурации поставщика несколько раз, повторные вхождения игнорируются. Если класс поставщика службы указан более чем в одном файле конфигурации, повторные вхождения игнорируются.

Поставщик службы, указанный в файле конфигурации поставщика, может находиться как в том же JAR-файле, что и файл конфигурации поставщика, так и в другом JAR-файле. Поставщик службы должен быть видим загрузчику классов, к которому изначально обращаются для поиска файла конфигурации поставщика; этот загрузчик не обязательно совпадает с загрузчиком классов, который в конечном итоге находит файл конфигурации поставщика.

Время поиска поставщиков

Поставщики служб загружаются и создаются отложенно, то есть по запросу. Загрузчик служб хранит кэш уже загруженных поставщиков. Каждый вызов метода iterator возвращает Iterator, который сначала выдает все элементы, сохраненные в кэше при предыдущих итерациях, в порядке создания экземпляров, а затем отложенно находит и создает экземпляры оставшихся поставщиков, поочередно добавляя их в кэш. Аналогично, каждый вызов метода stream возвращает Stream, который сначала обрабатывает всех поставщиков, загруженных при предыдущих операциях с потоками, в порядке загрузки, а затем отложенно находит оставшихся поставщиков. Кэши очищаются с помощью метода reload.

Ошибки

При использовании iterator загрузчика служб методы hasNext и next завершаются ошибкой и выбрасывают ServiceConfigurationError, если при поиске, загрузке или создании экземпляра поставщика службы возникает ошибка. При обработке потока загрузчика служб ServiceConfigurationError может быть выброшено любым методом, который вызывает поиск или загрузку поставщика службы.

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

  • Поставщика службы невозможно загрузить.
  • Поставщик службы не объявляет метод поставщика и при этом либо не присваивается интерфейсу/классу службы, либо не имеет конструктора поставщика.
  • Поставщик службы объявляет открытый статический метод без аргументов с именем "provider", тип возвращаемого значения которого не присваивается интерфейсу или классу службы.
  • Файл класса поставщика службы содержит более одного открытого статического метода без аргументов с именем "provider".
  • Метод поставщика, объявленный поставщиком службы, завершается ошибкой: он возвращает null или выбрасывает исключение.
  • Поставщик службы не объявляет метод поставщика, а его конструктор поставщика завершается ошибкой, выбрасывая исключение.

При чтении файла конфигурации поставщика, а также при загрузке или создании экземпляра класса поставщика, указанного в файле конфигурации поставщика, ServiceConfigurationError может быть выброшено по следующим причинам:

  • Формат файла конфигурации поставщика нарушает формат, указанный выше в разделе формат;
  • При чтении файла конфигурации поставщика возникает IOException;
  • Поставщика службы невозможно загрузить;
  • Поставщик службы не присваивается интерфейсу или классу службы, не определяет конструктор поставщика или не может быть создан.

Параллелизм

Экземпляры этого класса не являются потокобезопасными при одновременном использовании несколькими потоками.

Обработка null

Если не указано иное, передача аргумента null любому методу этого класса приводит к выбросу NullPointerException.

Начиная с версии:
1.6

Краткое описание вложенных классов

Модификатор и тип Класс Описание
static interface  ServiceLoader.Provider<S>
Представляет поставщика службы, найденного с помощью ServiceLoader.

Краткое описание методов

Модификатор и тип Метод Описание
Optional<S> findFirst()
Загрузить первого доступного поставщика службы этого загрузчика.
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> load(ModuleLayer layer, Class<S> service)
Создает новый загрузчик служб для заданного типа службы, загружающий поставщиков служб из модулей заданного уровня модулей и его предков.
static <S> ServiceLoader<S> loadInstalled(Class<S> service)
Создает новый загрузчик служб для заданного типа службы, используя загрузчик классов платформы.
void reload()
Очищает кэш поставщиков этого загрузчика, чтобы все поставщики были загружены заново.
Stream<ServiceLoader.Provider<S>> stream()
Возвращает поток для отложенной загрузки доступных поставщиков службы этого загрузчика.
String toString()
Возвращает строку с описанием этой службы.

Методы, объявленные в классе Object

clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait

Методы, объявленные в интерфейсе Iterable

forEach, spliterator

Подробное описание методов

iterator

public Iterator<S> iterator()
Возвращает итератор для ленивой загрузки и создания экземпляров доступных поставщиков служб этого загрузчика.

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

Кэширование: итератор, возвращаемый этим методом, сначала выдаёт все элементы кэша поставщиков в порядке их загрузки. Затем он лениво загружает и создаёт экземпляры всех оставшихся поставщиков служб, поочерёдно добавляя каждый из них в кэш. Если кэши поставщиков этого загрузчика очищены вызовом метода reload, существующие итераторы этого загрузчика служб следует отбросить. Методы итератора hasNext и next выбрасывают ConcurrentModificationException, если используются после очистки кэша поставщиков.

Итератор, возвращаемый этим методом, не поддерживает удаление. Вызов его метода remove приведёт к выбрасыванию UnsupportedOperationException.

Указано в:
iterator в интерфейсе Iterable<S>
Примечание API:
Выбрасывание ошибки в этих случаях может показаться чрезмерной мерой. Причина такого поведения заключается в том, что некорректный файл конфигурации поставщиков, как и некорректный файл класса, указывает на серьёзную проблему с конфигурацией виртуальной машины Java или её использованием. Поэтому предпочтительнее выбросить ошибку, а не пытаться восстановиться или, что ещё хуже, завершиться без сообщения об ошибке.
Возвращает:
Итератор, который лениво загружает поставщиков для службы этого загрузчика

stream

public Stream<ServiceLoader.Provider<S>> stream()
Возвращает поток для ленивой загрузки доступных поставщиков служб этого загрузчика. Элементы потока имеют тип Provider; для получения поставщика или создания его экземпляра необходимо вызвать метод get объекта Provider.

Для обеспечения ленивой загрузки фактический поиск поставщиков выполняется при обработке потока. Если поставщик службы не удаётся загрузить по какой-либо из причин, указанных выше в разделе Ошибки, метод, вызвавший загрузку поставщика службы, выбрасывает ServiceConfigurationError.

Кэширование: при обработке потока сначала обрабатываются поставщики, ранее загруженные операциями с потоком, в порядке загрузки. Затем лениво загружаются все оставшиеся поставщики служб. Если кэши поставщиков этого загрузчика очищены вызовом метода reload, существующие потоки этого загрузчика служб следует отбросить. Исходный spliterator возвращённого потока работает в режиме fail-fast и выбросит ConcurrentModificationException, если кэш поставщиков был очищен.

В следующих примерах показано использование. В первом примере создаётся поток объектов CodecFactory; второй пример аналогичен, за исключением того, что поставщики сортируются по имени класса поставщика (и таким образом находятся все поставщики).

   Stream<CodecFactory> providers = ServiceLoader.load(CodecFactory.class)
           .stream()
           .map(Provider::get);

   Stream<CodecFactory> providers = ServiceLoader.load(CodecFactory.class)
           .stream()
           .sorted(Comparator.comparing(p -> p.type().getName()))
           .map(Provider::get);
Возвращает:
Поток, который лениво загружает поставщиков для службы этого загрузчика
Начиная с версии:
9

load

public static <S> ServiceLoader<S> load(Class<S> service, ClassLoader loader)
Создаёт новый загрузчик служб для указанной службы. Для поиска поставщиков этой службы загрузчик служб использует указанный загрузчик классов в качестве начальной точки. Методы iterator и stream загрузчика служб ищут поставщиков как в именованных, так и в безымянных модулях следующим образом:
  • Шаг 1: поиск поставщиков в именованных модулях.

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

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

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

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

    Если модуль объявляет несколько поставщиков, они ищутся в порядке, в котором дескриптор модуля перечисляет поставщиков. Поставщики, динамически добавленные агентами инструментирования (см. redefineModule), всегда ищутся после поставщиков, объявленных модулем.

  • Шаг 2: поиск поставщиков в безымянных модулях.

    Поставщики служб в безымянных модулях ищутся, если их имена классов перечислены в файлах конфигурации поставщиков, найденных методом getResources загрузчика классов.

    Порядок определяется очередностью, в которой метод getResources загрузчика классов находит файлы конфигурации служб, а внутри файла — порядком перечисления имён классов.

    Любое упоминание в файле конфигурации поставщиков поставщика службы, развёрнутого в именованном модуле, игнорируется. Это позволяет избежать дублирования, которое иначе возникло бы, если бы именованный модуль содержал директиву provides и файл конфигурации поставщиков, в которых указан один и тот же поставщик службы.

    Класс поставщика должен быть виден загрузчику классов.

Примечание API:
Если путь классов загрузчика классов включает удалённые сетевые URL-адреса, при поиске файлов конфигурации поставщиков эти URL-адреса могут быть запрошены.

Это нормальное поведение, хотя оно может приводить к появлению непонятных записей в журналах веб-сервера. Однако если веб-сервер настроен неправильно, это поведение может привести к случайному сбою алгоритма загрузки поставщиков.

Веб-сервер должен возвращать ответ HTTP 404 (Not Found), если запрошенный ресурс не существует. Однако иногда веб-серверы ошибочно настраивают так, чтобы в таких случаях возвращался ответ HTTP 200 (OK) с информативной HTML-страницей ошибки. В результате при попытке этого класса разобрать HTML-страницу как файл конфигурации поставщиков будет выброшено ServiceConfigurationError. Лучшее решение этой проблемы — исправить неправильную настройку веб-сервера, чтобы он возвращал правильный код ответа (HTTP 404) вместе с HTML-страницей ошибки.

Параметры типа:
S — класс типа службы
Параметры:
service — интерфейс или абстрактный класс, представляющий службу
loader — загрузчик классов, используемый для загрузки файлов конфигурации поставщиков и классов поставщиков, или null, если следует использовать системный загрузчик классов (или, если он недоступен, загрузчик классов начальной загрузки)
Возвращает:
Новый загрузчик служб
Выбрасывает:
ServiceConfigurationError — если тип службы недоступен вызывающему коду или вызывающий код находится в явном модуле, дескриптор которого не объявляет использование service

load

public static <S> ServiceLoader<S> load(Class<S> service)
Создаёт новый загрузчик служб для указанного типа службы, используя контекстный загрузчик классов текущего потока.

Вызов этого вспомогательного метода в форме

    ServiceLoader.load(service)
эквивалентен
    ServiceLoader.load(service, Thread.currentThread().getContextClassLoader())
Примечание API:
Объекты загрузчика служб, полученные с помощью этого метода, не следует кэшировать на уровне всей виртуальной машины. Например, у разных приложений в одной виртуальной машине могут быть разные контекстные загрузчики классов потоков. Поиск, выполненный одним приложением, может найти поставщика службы, видимого только через его контекстный загрузчик классов потока и потому недоступного для поиска другим приложением. Также возможны утечки памяти. В некоторых приложениях может подойти локальная переменная потока.
Параметры типа:
S — класс типа службы
Параметры:
service — интерфейс или абстрактный класс, представляющий службу
Возвращает:
Новый загрузчик служб
Выбрасывает:
ServiceConfigurationError — если тип службы недоступен вызывающему коду или вызывающий код находится в явном модуле, дескриптор которого не объявляет использование service

loadInstalled

public static <S> ServiceLoader<S> loadInstalled(Class<S> service)
Создаёт новый загрузчик служб для указанного типа службы, используя загрузчик классов платформы.

Этот вспомогательный метод эквивалентен:

    ServiceLoader.load(service, ClassLoader.getPlatformClassLoader())

Этот метод предназначен для случаев, когда нужны только установленные поставщики. Полученная служба будет находить и загружать только поставщиков, установленных в текущей виртуальной машине Java; поставщики из пути модулей или пути классов приложения будут игнорироваться.

Параметры типа:
S — класс типа службы
Параметры:
service — интерфейс или абстрактный класс, представляющий службу
Возвращает:
Новый загрузчик служб
Выбрасывает:
ServiceConfigurationError — если тип службы недоступен вызывающему коду или вызывающий код находится в явном модуле, дескриптор которого не объявляет использование service

load

public static <S> ServiceLoader<S> load(ModuleLayer layer, Class<S> service)
Создаёт новый загрузчик служб для указанного типа службы, чтобы загружать поставщиков служб из модулей указанного слоя модулей и его предков. Поиск поставщиков в безымянных модулях не выполняется. Порядок, в котором методы iterator и stream загрузчика служб ищут поставщиков и выдают элементы, описан ниже:
  • Поставщики ищутся в слое модулей до поиска поставщиков в родительских слоях. Обход родительских слоёв выполняется в глубину, при этом каждый слой посещается не более одного раза. Например, предположим, что L0 — загрузочный слой, а L1 и L2 — слои модулей, родителем которых является L0. Теперь предположим, что L3 создан с родителями L1 и L2 (в указанном порядке). При поиске поставщиков с помощью загрузчика служб, использующего L3 в качестве контекста, поставщики будут найдены в следующем порядке: L3, L1, L0, L2.

  • Если модуль объявляет несколько поставщиков, они ищутся в порядке, в котором дескриптор модуля перечисляет поставщиков. Поставщики, динамически добавленные агентами инструментирования, всегда ищутся после поставщиков, объявленных модулем.

  • Порядок модулей в слое модулей не определён.

Примечание API:
В отличие от других определённых здесь методов load, тип службы является вторым параметром. Это сделано для предотвращения проблем с совместимостью исходного кода для кода, использующего load(S, null).
Параметры типа:
S — класс типа службы
Параметры:
layer — слой модулей
service — интерфейс или абстрактный класс, представляющий службу
Возвращает:
Новый загрузчик служб
Выбрасывает:
ServiceConfigurationError — если тип службы недоступен вызывающему коду или вызывающий код находится в явном модуле, дескриптор которого не объявляет использование service
Начиная с версии:
9

findFirst

public Optional<S> findFirst()
Загружает первого доступного поставщика службы этого загрузчика. Этот вспомогательный метод эквивалентен вызову метода iterator() и получению первого элемента. Поэтому он возвращает первый элемент из кэша поставщиков, если это возможно; в противном случае он пытается загрузить и создать экземпляр первого поставщика.

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

   CodecFactory factory = ServiceLoader.load(CodecFactory.class)
                                       .findFirst()
                                       .orElse(DEFAULT_CODECSET_FACTORY);
Возвращает:
Первый поставщик службы или пустой Optional, если поставщики служб не найдены
Выбрасывает:
ServiceConfigurationError — если класс поставщика не удаётся загрузить по любой из причин, указанных выше в разделе Ошибки.
Начиная с версии:
9

reload

public void reload()
Очищает кэш поставщиков этого загрузчика, чтобы все поставщики были загружены повторно.

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

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

toString

public String toString()
Возвращает строку с описанием этой службы.
Переопределяет:
toString в классе Object
Возвращает:
Строка с описанием

Сообщить об ошибке или предложить улучшение
Дополнительную справочную информацию по API и документацию для разработчиков см. в документации Java SE, содержащей более подробные описания для разработчиков, включая концептуальные обзоры, определения терминов, обходные решения и рабочие примеры кода. Другие версии.
Java является товарным знаком или зарегистрированным товарным знаком Oracle и/или её аффилированных лиц в США и других странах.
Авторское право © 1993, 2025, Oracle и/или её аффилированные лица, 500 Oracle Parkway, Redwood Shores, CA 94065 USA.
Все права защищены. Использование регулируется условиями лицензии и политикой распространения документации.

© 1993, 2025, Oracle and/or its affiliates. All rights reserved.
Documentation extracted from Debian's OpenJDK Development Kit package.
Licensed under the GNU General Public License, version 2, with the Classpath Exception.
Various third party code in OpenJDK is licensed under different licenses (see Debian package).
Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.
https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/util/ServiceLoader.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API