Механизмы Java SPI, которые вы должны знать

Java
Механизмы Java SPI, которые вы должны знать

предисловие

Я не знаю, пошли ли вы в компанию, чтобы возобновить работу сейчас. Я работаю из дома почти 3 недели, и я также оставался дома больше месяца. К счастью, моя работа не пострадала в в любом случае.Я лично считаю, что удаленная работа и ИТ-индустрия очень совместимы.За это время эффективность работы даже выше, чем в офисе, и, поскольку бизнес нашей компании находится за границей, эпидемия почти не оказала большого влияния.

Слишком далеко, на этот раз я в основном хочу поделиться с вамиJavaизSPIмеханизм. На выходных делать нечего, пролистал ранее написанный блог«Проектирование подключаемого контейнера IOC», обнаружил, что реализация в то время была не такой элегантной.

Для тех из вас, кто еще не видел его, я сначала сделаю краткое изложение перспектив, потребностей на тот момент:

Я реализовал аналогичный SpringMVC, но очень легкий http-фреймворк.cicada, что, конечно, также требует контейнера IOC, в котором могут храниться все одноэлементные компоненты.

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

cicada8-spi.md---0082zybply1gc6sqv3gp4j30zm0u0n8c.jpg

Позвольте мне показать вам разницу между двумя реализациями.Во-первых, с точки зрения простоты кода, этоSPIДаже лучше.

Что такое СПИ

Прежде чем мы приступим к подробному анализу, мы должны сначала понятьSPIчто это?

Прежде всего этоService provider interfaceАббревиатура , переведенная на китайский язык, означает сервис, предоставляющий интерфейс обнаружения.

Но не смущайтесь термином здесь,服务发现Это не то же самое, что обнаружение сервисов в микросервисах, о которых мы часто слышим.

как указано вышеIOCСуществует несколько реализаций контейнеров A, B, C (которые можно понимать как службы), и мне нужно знать во время выполнения, какую конкретную реализацию следует использовать.

На самом деле это по сути типичное интерфейсно-ориентированное программирование, на что неоднократно обращали внимание, когда мы только начинали изучать программирование.

Практика СПИ

Далее давайте посмотрим, как использовать SPI для реализации только что упомянутого сменного контейнера IOC.

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

cicada8-spi.md---0082zybply1gc6tlhql39j31490u0wjj.jpg

который содержит некоторыеBeanОперации, требуемые контейнером: регистрация, получение, выпуск бинов.

Чтобы другие реализовали своиIOCконтейнер, поэтому выносим этот интерфейс в отдельныйModule, которые могут быть импортированы другими.

cicada8-spi.md---0082zybply1gc6tobsdgwj30u40ewdh1.jpg

Поэтому, когда я хочу реализовать синглтонIOCконтейнер, мне просто нужно создать новыйModuleЗатем импортируйте модуль прямо сейчас и внедритеCicadaBeanFactoryинтерфейс.

Конечно, самое главное, чтоresourcesСоздайте новый в каталогеMETA-INF/services/top.crossoverjie.cicada.base.bean.CicadaBeanFactoryфайл, имя файла должно быть полным именем интерфейса, который мы определили ранее (спецификация SPI).

cicada8-spi.md---0082zybply1gc6ts164zlj30uk0amq3x.jpg

Контент — это полное имя нашего собственного класса реализации:

top.crossoverjie.cicada.bean.ioc.CicadaIoc

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

Просто Java уже предоставила API для блокировки этого процесса:

    public static CicadaBeanFactory getCicadaBeanFactory() {
        ServiceLoader<CicadaBeanFactory> cicadaBeanFactories = ServiceLoader.load(CicadaBeanFactory.class);
        if (cicadaBeanFactories.iterator().hasNext()){
            return cicadaBeanFactories.iterator().next() ;
        }

        return new CicadaDefaultBean();
    }

когдаclasspathЕсли есть наш только класс реализации (представляющий пакет jar класса реализации), мы можем передатьjava.util.ServiceLoaderКласс инструмента для поиска всех классов реализации (одновременно может быть несколько классов реализации, но обычно нам нужен только один).


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

    <dependency>
        <groupId>top.crossoverjie.opensource</groupId>
        <artifactId>cicada-ioc</artifactId>
        <version>2.0.4</version>
    </dependency>

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

Это делает его гибким без изменения строки кода.可拔插выберитеIOCконтейнер тоже.

Некоторые другие приложения SPI

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

НапримерDubboРяд расширений предоставляется в:

cicada8-spi.md---0082zybply1gc6ue6zubvj30gq0pymyq.jpg

того же типаRPCРамкаmotanРасширение ответа также доступно в:

cicada8-spi.md---0082zybply1gc6ufacqt5j30lm0j8q5j.jpg

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

НапримерmotanизspiРазрешено ли быть синглтоном и так далее.

Другим примером является пакет драйверов MySQL, который использует SPI для реализации собственной логики подключения.

cicada8-spi.md---0082zybply1gc6uqg2ga2j30ii0bmdgz.jpg

Суммировать

JavaсвояSPIНа самом деле есть небольшие недостатки, такие как:

  • Неэффективно просматривать и загружать все классы реализации.
  • когда несколькоServiceLoaderв то же времяloadВремя от времени возникают проблемы с параллелизмом (хотя никто этого не делает).

Наконец, подводя итог,SPIЭто не какая-то передовая технология, сутью является интерфейсно-ориентированное программирование, а сам интерфейс-ориентированный навык также является необходимым навыком в нашей повседневной разработке, поэтому поймите использованиеSPIТакже очень полезно.

Весь исходный код этой статьи:

GitHub.com/вместе ОС/…

Ваши лайки и репост - лучшая поддержка для меня