предисловие
Я не знаю, пошли ли вы в компанию, чтобы возобновить работу сейчас. Я работаю из дома почти 3 недели, и я также оставался дома больше месяца. К счастью, моя работа не пострадала в в любом случае.Я лично считаю, что удаленная работа и ИТ-индустрия очень совместимы.За это время эффективность работы даже выше, чем в офисе, и, поскольку бизнес нашей компании находится за границей, эпидемия почти не оказала большого влияния.
Слишком далеко, на этот раз я в основном хочу поделиться с вамиJava
изSPI
механизм. На выходных делать нечего, пролистал ранее написанный блог«Проектирование подключаемого контейнера IOC», обнаружил, что реализация в то время была не такой элегантной.
Для тех из вас, кто еще не видел его, я сначала сделаю краткое изложение перспектив, потребностей на тот момент:
Я реализовал аналогичный SpringMVC, но очень легкий http-фреймворк.cicada, что, конечно, также требует контейнера IOC, в котором могут храниться все одноэлементные компоненты.
Я надеюсь, что есть много способов реализовать этот IOC-контейнер и даже предоставить интерфейс для реализации другими; конечно, процесс переключения этого IOC-контейнера не должен быть жестко закодирован, о чем здесь упоминается.Подключаемый. Когда я хочу использовать реализацию A, я импортирую jar-пакет A, а когда я использую B, я импортирую пакет B.
Позвольте мне показать вам разницу между двумя реализациями.Во-первых, с точки зрения простоты кода, этоSPI
Даже лучше.
Что такое СПИ
Прежде чем мы приступим к подробному анализу, мы должны сначала понятьSPI
что это?
Прежде всего этоService provider interface
Аббревиатура , переведенная на китайский язык, означает сервис, предоставляющий интерфейс обнаружения.
Но не смущайтесь термином здесь,服务发现
Это не то же самое, что обнаружение сервисов в микросервисах, о которых мы часто слышим.
как указано вышеIOC
Существует несколько реализаций контейнеров A, B, C (которые можно понимать как службы), и мне нужно знать во время выполнения, какую конкретную реализацию следует использовать.
На самом деле это по сути типичное интерфейсно-ориентированное программирование, на что неоднократно обращали внимание, когда мы только начинали изучать программирование.
Практика СПИ
Далее давайте посмотрим, как использовать SPI для реализации только что упомянутого сменного контейнера IOC.
Поскольку только что было упомянуто, что суть SPI заключается в интерфейсно-ориентированном программировании, то, естественно, нам сначала нужно определить интерфейс:
который содержит некоторыеBean
Операции, требуемые контейнером: регистрация, получение, выпуск бинов.
Чтобы другие реализовали своиIOC
контейнер, поэтому выносим этот интерфейс в отдельныйModule
, которые могут быть импортированы другими.
Поэтому, когда я хочу реализовать синглтонIOC
контейнер, мне просто нужно создать новыйModule
Затем импортируйте модуль прямо сейчас и внедритеCicadaBeanFactory
интерфейс.
Конечно, самое главное, чтоresources
Создайте новый в каталогеMETA-INF/services/top.crossoverjie.cicada.base.bean.CicadaBeanFactory
файл, имя файла должно быть полным именем интерфейса, который мы определили ранее (спецификация SPI).
Контент — это полное имя нашего собственного класса реализации:
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
Ряд расширений предоставляется в:
того же типаRPC
Рамкаmotan
Расширение ответа также доступно в:
То, как они используются, очень похоже на Java SPI, но принцип немного отличается, а также добавлены некоторые новые функции.
Напримерmotan
изspi
Разрешено ли быть синглтоном и так далее.
Другим примером является пакет драйверов MySQL, который использует SPI для реализации собственной логики подключения.
Суммировать
Java
свояSPI
На самом деле есть небольшие недостатки, такие как:
- Неэффективно просматривать и загружать все классы реализации.
- когда несколько
ServiceLoader
в то же времяload
Время от времени возникают проблемы с параллелизмом (хотя никто этого не делает).
Наконец, подводя итог,SPI
Это не какая-то передовая технология, сутью является интерфейсно-ориентированное программирование, а сам интерфейс-ориентированный навык также является необходимым навыком в нашей повседневной разработке, поэтому поймите использованиеSPI
Также очень полезно.
Весь исходный код этой статьи:
Ваши лайки и репост - лучшая поддержка для меня