Класс 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-each) для получения экземпляров поставщиков службы, которые были найдены:

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;
     provides com.example.CodecFactory with 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. Пробелы и символы табуляции вокруг имени каждого поставщика службы, а также пустые строки игнорируются. Символ комментария — это '#' ('&#92;u0023' ДИЕЗ); в каждой строке все символы после первого символа комментария игнорируются. Если имя класса поставщика службы указано более одного раза в файле конфигурации поставщика, то дубликат игнорируется. Если имя класса поставщика службы указано в нескольких файлах конфигурации, то дубликат игнорируется.

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

Время обнаружения поставщика

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

Ошибки

При использовании итератора загрузчика службы методы 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()

Возвращает строку, описывающую эту службу.

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

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

Методы, объявленные в интерфейсе java.lang.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, метод Provider get должен быть вызван для получения или создания поставщика.

Для достижения ленивой загрузки фактическая работа по поиску поставщиков выполняется при обработке потока. Если поставщик службы не может быть загружен по любой причине, указанной в разделе Ошибки выше, то 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: Поиск поставщиков в именованных модулях.

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

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

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

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

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

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

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

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

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

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

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

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

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

Типы параметров:
S - класс типа службы
Параметры:
service - Интерфейс или абстрактный класс, представляющий службу
loader - Загрузчик классов, используемый для загрузки файлов конфигурации поставщиков и классов поставщиков, или null если нужно использовать системный загрузчик классов (или, если это не удается, загрузчик Bootstrap)
Возвращает:
Новый загрузчик служб
Бросает:
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(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
Возвращает:
Строка описания

© 1993, 2020, 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/11/docs/api/java.base/java/util/ServiceLoader.html

Spec-Zone .ru
спецификации, руководства, описания, API