1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/javacoo-xkernel

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
README.md 16 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
gitlife-traslator Отправлено 01.12.2024 21:02 5647fb8

xkernel микроядро системы инструменты

Фон

SPI (Service Provider Interface) — это набор интерфейсов, предоставляемых Java, который используется для расширения или замены компонентов третьими сторонами. SPI позволяет находить реализации сервисов для расширенных API. Из принципа работы Java SPI можно понять, что у механизма Java SPI есть следующие недостатки:

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

Архитектура программного обеспечения

Описание архитектуры программного обеспечения

Диаграмма структуры класса

Схема проектирования микроядра

Процесс схемы потока загрузки ExtensionLoader класса

Микроядро не взаимодействует с конкретными реализациями точек расширения. ExtensionLoader связывает точки расширения с их конкретными реализациями. Микроядру нужно знать только о себе и ExtensionLoader. Точки расширения могут меняться, а ядро остаётся неизменным.

  • Термины:
    • SPI: Service Provider Interface.
    • Точка расширения: интерфейс, аннотированный @Spi, является точкой расширения.
    • Расширение: реализация интерфейса, аннотированного @Spi, называется расширением этой точки расширения.
  • Соглашения о точках расширения:
    • Точки расширения должны быть интерфейсами, должны быть аннотированы @Spi и соответствовать этим двум условиям.
  • Определения расширений:
    • В путях META-INF/services/$имя интерфейса расширения, META-INF/ext/$имя интерфейса расширения и META-INF/ext/internal/$имя интерфейса расширения файлы с именами, совпадающими с полными именами классов интерфейсов расширения, определяют реализации точек расширения. Например, файл META-INF/ext/com.ximg.api.ImgHandler определяет расширение: thumbnailator=com.ximg.impl.ThumbnailatorImgHandler
  • По умолчанию расширения:
    • Если интерфейс аннотируется @Spi("abc"), то расширение по умолчанию для этой точки расширения — это расширение, указанное в конфигурационном файле SPI с ключом "abc".
  • Аннотация Spi: эта аннотация применяется к интерфейсам точек расширения. Значение свойства value используется для указания имени расширения по умолчанию. Определение: @Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface Spi { String value() default ""; }
  • ExtensionLoader: загрузчик реализаций точек расширения.
    • Загрузчик расширений является основным компонентом этого решения. Он управляет инициализацией и загрузкой расширений внутренних точек расширения.
    • Включает статические атрибуты: EXTENSION_LOADERS: хранит экземпляры ExtensionLoader для открытых точек расширения ядра. EXTENSION_INSTANCES: сохраняет типы расширений (классы) и экземпляры типов расширений. type: аннотируемый интерфейс @SPI, то есть точка расширения. cachedNames: имена расширений, которые не соответствуют режиму декорирования (существует только один параметр, и параметр является конструктором экземпляра типа расширения). cachedClasses: классы расширений без соответствия режиму декорирования, имя расширения используется как ключ, класс экземпляра используется как значение. cachedInstances: имя расширения и экземпляр объекта, имя расширения является ключом, экземпляр расширения является значением. cachedDefaultName: расширение по умолчанию, указанное аннотацией @SPI на точке расширения. cachedWrapperClasses: расширения, соответствующие режиму декорирования. exceptions: исключения, возникающие при загрузке конфигурационного файла расширения во время процесса загрузки расширения, ключ — это текущая строка конфигурации расширения, значение — выброшенное исключение.
  • Процесс загрузки класса:
    • Сначала получите экземпляр ExtensionLoader через метод getExtensionLoader ExtensionLoader, затем получите объект класса расширения через метод ExtensionLoader getExtension. Среди них метод getExtensionLoader используется для получения ExtensionLoader из кэша, соответствующего классу расширения. Если в кэше нет совпадения, создайте новый экземпляр. Основные шаги: a. Метод T getExtension(String name): сначала проверьте кэш. Если кэш не совпадает, создайте объект расширения. b. Метод T createExtension(String name), включающий следующие шаги: i. Получите все классы расширения через getExtensionClasses. ii. Создайте объект расширения через отражение. c. Map<String, Class>> getExtensionClasses(): перед получением класса расширения в соответствии с именем расширения необходимо сначала проанализировать отношение сопоставления между именем расширения и классом расширения (Map) в соответствии с конфигурационным файлом, а затем получить соответствующий класс расширения в соответствии с именем расширения. Здесь также сначала проверяется кэш, если кэш не совпадает, он блокируется с помощью synchronized. После повторной проверки кэша и определения того, что classes всё ещё пуст, загрузите классы расширения через loadExtensionClasses. d. Map> loadExtensionClasses(): метод loadExtensionClasses выполняет две вещи: анализирует аннотацию @Spi и вызывает метод loadDirectory для загрузки конфигурационных файлов в указанном каталоге. e. Void loadDirectory(Map<String, Class>> extensionClasses, String dir): метод loadDirectory сначала получает все ссылки на ресурсы через classLoader, а затем загружает ресурсы через loadResource. f. Void loadResource(Map> extensionClasses, ClassLoader classLoader, java.net.URL resourceURL): метод loadResource используется для чтения и анализа конфигурационных файлов и загрузки классов через отражение, а затем вызова метода loadClass для выполнения других операций. g. void loadClass(Map<String, Class>> extensionClasses, java.net.URL resourceURL, Class> clazz, String name) throws NoSuchMethodException: метод loadClass в основном используется для управления кешем, таким как cachedAdaptiveClass, cachedWrapperClasses и cachedNames. Используя этот инструмент, вы можете быстро разработать расширяемую структуру разработки на основе микроядер и плагинов, которая не требует изменения исходного кода для реализации расширения, развязки и расширения, которое почти не вторгается в исходный код. Просто добавьте конфигурацию для достижения расширения. Она соответствует принципу открытия и закрытия.

Руководство по установке

Импортируйте основной пакет микроядерной системы.

      <dependency>
    <groupId>com.javacoo</groupId>
    <artifactId>xKernel</artifactId>
    <version>1.0.0</version>
      </dependency>

Инструкция по применению

  1. Разработайте интерфейс класса, который необходимо расширить, например:
/**
 * Обработка данных
 * <p>Объяснение:</p>
 * <li></li>
 *
 * @Author DuanYong
 * @Since 2019/8/30 23:41
 * @Version 1.0
 */
public interface DataHandler<T> {
    /**
     * Обработать
     * <p>Объяснение:</p>
     * <li></li>
     * @Author DuanYong
     * @Since 2019/8/30 23:42
     * @Version 1.0
     * @Params data
     */
    void handle(final T data);
} **2. В интерфейсе добавить аннотацию @Spi, например:**

/**

  • Обработка данных
  • Описание:

  • @Author DuanYong
  • @Since 2019/8/30 23:41
  • @Version 1.0 / @Spi("default") public interface DataHandler { /*
    • Обработка
    • Описание:

  • @Author DuanYong
  • @Since 2019/8/30 23:42
  • @Version 1.0
  • @Params data */ void handle(final T data); }

**3. Реализовать расширенный интерфейс класса.**

/**

  • Абстрактный класс обработки данных

  • Описание:

  • @Author DuanYong

  • @Since 2019/8/30 23:47

  • @Version 1.0 / @Slf4j public abstract class AbstractDataHandler implements DataHandler { protected ExecutorService executorService = new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors(), Runtime.getRuntime().availableProcessors(), 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue(),Executors.defaultThreadFactory()); @Override public final void handle(final String data){ executorService.submit(()->{ //Разбор T t = parser(data); if(null == t){ return; } //Выполнение обработки doHandle(t); }); } /*

    • Выполнение обработки
    • Описание:

  • @Author DuanYong
  • @Since 2019/8/30 23:57
  • @Version 1.0
  • @Params t */ protected abstract void doHandle(T t);

/**

  • Разбор данных
  • Описание:

  • @Author DuanYong
  • @Since 2019/8/30 23:55
  • @Version 1.0
  • @Params rawData исходные данные
  • @Return T */ protected abstract T parser(String rawData);

}


**4. В каталоге проекта или jar-пакета META-INF/services/или META-INF/ext или META-INF/ext/internal создать текстовый файл с именем, совпадающим с полным именем интерфейса, и содержанием в формате:**

* реализация имени = реализация класса полного имени.*

Файл: com.javacoo.swing.api.data.DataHandler Содержание: default=com.javacoo.swing.core.data.AliPayDataHandler


**5. Используя метод ExtensionLoader.getExtensionLoader(интерфейс типа), получить экземпляр объекта ExtensionLoader<интерфейс типа> для соответствующего интерфейса типа.**

/*Обработка данных/ private DataHandler dataHandler; public MyNetworkDelegate(){ dataHandler = ExtensionLoader.getExtensionLoader(DataHandler.class).getDefaultExtension(); }


**6. Используя экземпляр объекта ExtensionLoader<интерфейсный тип>, вызвать метод getExtension(расширение точки имени) для получения расширения реализации, соответствующей расширению точки имени.**

#### Участие в проекте

1. Форк этого репозитория.
2. Создать ветку Feat_xxx.
3. Отправить код.
4. Создать Pull Request.

#### Навыки Code Cloud

1. Использование Readme_XXX.md для поддержки разных языков, таких как Readme_en.md, Readme_zh.md.
2. Официальный блог Code Cloud [blog.gitee.com](https://blog.gitee.com).
3. Вы можете [https://gitee.com/explore](https://gitee.com/explore) этот адрес, чтобы узнать о выдающихся проектах с открытым исходным кодом на Code Cloud.
4. GVP (Gitee Value Project) — это проект с открытым исходным кодом, который был всесторонне оценён Code Cloud как выдающийся.
5. Официальное руководство по использованию Code Cloud [https://gitee.com/help](https://gitee.com/help).
6. Лица обложки Code Cloud — это серия, которая демонстрирует стиль членов Code Cloud [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/).

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/javacoo-xkernel.git
git@api.gitlife.ru:oschina-mirror/javacoo-xkernel.git
oschina-mirror
javacoo-xkernel
javacoo-xkernel
master