предисловие
Когда дело доходит до Dubbo, мы не можем избежать идеи SPI, потому что это очень важная часть ядра Dubbo, но SPI — это большая тема.Эта статья и предыдущиеАнализ исходного кода Dubbo — простой принцип, интеграция с SpringТочно так же это статья для разогрева знаний на тему анализа исходного кода Dubbo.实际项目
Я использовал SPI от Dubbo. Позже я поделюсь с вами тем, как использовать SPI в нашем реальном проекте и как мы оптимизировали SPI в будущем.
Вопросы для интервью в прямом эфире
-
ты понимаешь
spi
, подскажите что такое spi и зачем использовать spi? -
Вы понимаете механизм загрузки классов?Расскажите, что такое режим родительского делегирования, какие у него есть недостатки, есть ли знакомые случаи этого недостатка и каков принцип решения этого недостатка?
Краткое введение в spi
если упоминаетсяapi
Я верю, что все знают,spi
Если да, то об этом знает меньше людей.
Проще говоря,api
для пользователей,spi
Это для разработчиков.Хороший фреймворк с открытым исходным кодом должен оставлять некоторые точки расширения.Пусть участники пытаются расширяться в черном ящике вместо того, чтобы модифицировать код в белом ящике, иначе будет сложно управлять ответвлениями, качеством, слияниями и конфликтами. И фреймворк То, что может автор, может сделать и разработчик.
С точки зрения использования, это динамическое добавление классов реализации в интерфейс во время выполнения.IoC
идея вынесения управления сборкой за пределы программы
Если говорить на примере из жизни, типа плагина для браузера, например, если вилки в стене не хватает, вместо смены вилки мы подключим удлинитель (это не очень уместно, так вы его временно так неравномерно поймёте на ранней стадии))
Никакое количество слов не является абстрактным, поэтому давайте воспользуемся кодом, чтобы просто реализовать его.spi
Простая реализация spi
Интерфейсы и конкретные классы реализации
public interface ISayName {
void say();
}
public class SayEnglishName implements ISayName{
@Override
public void say() {
System.out.println("Toby");
}
}
public class SayChineseName implements ISayName{
@Override
public void say() {
System.out.println("肥朝");
}
}
конфигурационный файл, который необходимо поместить вMETA-INF/services/接口全限定名
com.toby.spi.impl.SayChineseName
com.toby.spi.impl.SayEnglishName
демонстрационная структура каталогов
Результаты теста следующие
Изменяя файл конфигурации, мы можем динамически изменять класс реализации интерфейса.
Внимательные друзья могут обнаружить, что, например, я хочу добавить класс реализацииSayFranceNameImpl
, в этом случае еще мало изменить конфигурационный файл, а есть класс реализации в препаке.
Не беспокойтесь об этом, это будет представлено позжеjavassist
, то есть технология динамического байт-кода. Таким образом, классы Java могут динамически генерироваться во время выполнения, и нет необходимости заранее помещать в пакет класс реализации интерфейса. Для получения дополнительной информации просто обратите внимание на Feichao.
Конечно, осторожные друзья могли найти его, мне даже это не нужноspi
, я использую весенниеioc
Вы также можете динамически внедрять различные классы реализации через файл конфигурации.
Например, при разработке dubbo я не хочу сильно полагаться на контейнер IoC Spring, но я также чувствую, что он немного перегружен для создания небольшого контейнера IoC. на любых сторонних библиотеках.Оригинальные слова из официальных документов такие
Теоретически Dubbo может полагаться только на JDK для работы без каких-либо сторонних библиотек, просто настройте и используйте стратегии реализации, связанные с JDK.
Стук по доске
Я часто вижу, как люди задают два типа вопросов
- С таким количеством Java-людей он насыщен?
- Почему всегда нужно брать интервью, чтобы построить ракету, а потом пойти и закрутить гайку?
Вы можете спросить своего коллегу, знаете ли вы, что такоеspi
, если он не знает, как вы думаете, сколько времени ему потребуется, чтобы реализовать приведенный выше простой пример?使用
На этом уровне трудно эффективно выделиться.Независимо от того, что вы делаете, если вы хотите выделиться среди конкурентов, вы должны произнести три слова.差异化
.
Две области, которые легче различить в Java Foundation:JVM
и并发编程
Если вы остаетесь только на уровне использования, то нет смысла обращать внимание на блог Фей Чао, поэтому содержание этой статьиspi
также нужноClassLoader
Объединить.
учитьсяJVM
и并发编程
Покупка этой книги имеет важное значение, ссылка на следующее содержание实战Java虚拟机
.если вы посмотрите на深入Java虚拟机
Неважно, не запутайтесь в каналах получения знаний, никого не волнует, делаете ли вы пятилетний вступительный экзамен в колледж, трехлетнюю симуляцию или же королеву-голодный случай.
Следующее содержание отражает часть основного содержания книги, большое спасибо за тяжелую работу автора (я надеюсь, что все поддержат настоящую книгу).
Получить spi из ClassLoader
Краткое введение в ClassLoader
Class
из装载
можно условно разделить на加载类
,连接类
и初始化
три этапа, на которых всеClass
все поClassLoader
Загрузка, а затем виртуальная машина Java отвечает за подключение, инициализацию и другие операции, то есть она не может пройтиClassLoader
чтобы изменить поведение соединения и инициализации класса.
Виртуальная машина Java создает три категорииClassLoader
, соответственно
BootStrap ClassLoader(启动类加载器)
Extension ClassLoader(扩展类加载器)
APP ClassLoader(应用类加载器,也称为系统类加载器)
Кроме того, каждое приложение может также自定义ClassLoader
Родительский режим делегирования ClassLoader
существуетClassLoader
В структуре также есть важное полеparent
, это тожеClassLoader
Например, это поле поле представляетClassLoader
также стать этимClassLoader
Родители класса.В процессе загрузки класса некоторые запросы могут быть переданы для обработки их собственным родителям.
Как показано на рисунке,应用类加载器
родители扩展类加载器
,扩展类加载器
родители启动类加载器
.
в системеClassLoader
При совместной работе по умолчанию используется双亲委托模式
.То есть при загрузке класса система будет определять загружен ли текущий класс.Если он загружен,то сразу вернет доступный класс.В противном случае попытается загрузить.При попытке загрузки будет сначала запросите родителей для обработки.Если запрос родителей Если это не удается, он загрузится сам.
Недостатки модели родительского делегирования
При оценке того, загружен ли класс, загрузчик класса приложения будет оценивать вверх по родительскому пути до тех пор, пока загрузчик класса не будет запущен.Но загрузчик запускаемого класса не будет запрашивать вниз, этот маршрут делегирования является односторонним, то есть класс уровня загружен загрузчиком, не может получить доступ к классам, загруженным базовым загрузчиком классов, как показано на рисунке
Класс в загрузчике классов запуска является основным классом системы.Например, в системном классе предоставляется интерфейс, а интерфейс также предоставляет фабричный метод для создания экземпляра интерфейса, но класс реализации интерфейс используется на уровне приложения, интерфейс и фабричный метод находятся в загрузчике классов запуска, возникнет проблема, заключающаяся в том, что фабричный метод не может создать экземпляр приложения, загружаемый загрузчиком класса приложения.
Есть много компонентов, которые имеют эту проблему, например,JDBC
,Xml parser
И т. д. Сам JDBC является стандартом для java для подключения к базе данных. Это уровень абстракции для подключения к базе данных. Он состоит из набора классов и интерфейсов, написанных на java. Реализация интерфейса завершается каждым производителем базы данных.
Дополнение к модели родительского делегирования
В Java базовый класс (rt.jar) предоставляет внешние сервисы, которые могут быть реализованы на самом прикладном уровне.spi
, Тогда давайте посмотрим, в启动类加载器
, доступ к应用类加载器
Принцип реализации spi интерфейса
Thread
В классе есть два метода
public ClassLoader getContextClassLoader()//获取线程中的上下文加载器
public void setContextClassLoader(ClassLoader cl)//设置线程中的上下文加载器
Благодаря этим двум методамClassLoader
помещается в экземпляр потока, чтобыClassLoader
Станьте относительно общим экземпляром. Таким образом, даже код в загрузчике классов запуска может получить доступ к классам в загрузчике классов приложения. Как показано ниже
напиши в конце
Feichao — это технический публичный аккаунт, в котором основное внимание уделяется принципам, исходному коду и навыкам разработки, оригинальному тематическому анализу исходного кода в аккаунте и реальному сражению принципов исходного кода в реальных сценах (ключевые моменты).Отсканируйте QR-код нижеОбратите внимание на Фей Чао, пусть те, кто должен строить ракеты, перестанут трахаться!