Понимание концепций OSGi. Попробуйте следовать подходу головоломки

Опубликовано: 2013-04-20

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

Чтобы понять концепции OSGi, мы попытаемся следовать подходу головоломки, идея состоит в том, чтобы начать с тривиальной части этой технологии и искать другие части, связанные с найденными. А собрать пазл нам поможет JArchitect, который поможет обнаружить внутренний дизайн OSGi.

Чтобы быть более конкретным, мы анализируем с помощью JArchitect приложение, использующее технологию OSGi, это относится к известной IDE eclipse, которая использует равноденствие контейнера OSGi.

Начнем с типичного определения OSGi:

OSGi снижает сложность, предоставляя модульную архитектуру для современных крупномасштабных распределенных систем, а также для небольших встроенных приложений. Построение систем из собственных и готовых модулей значительно снижает сложность и, следовательно, затраты на разработку и обслуживание. Модель программирования OSGi реализует перспективность компонентных систем.

Тривиальная часть OSGi — это модульность, давайте узнаем, что такое модули OSGi?

Модули OSGI называются пакетами, поэтому каждое приложение состоит как минимум из одного пакета.
Эти пакеты выполняются внутри контейнера, и поскольку каждый модульный подход, когда контейнер управляет модулями, возникает вопрос, какой контракт должен реализовывать каждый модуль, чтобы быть интегрированным в контейнер?

Возьмем в качестве примера связку org.eclipse.equinox.jsp.jasper и найдем все ее реализованные интерфейсы, для этого мы можем выполнить следующий запрос CQLinq:

затмение4

Реализован интерфейс BundleActivator из пакета OSGi, этот интерфейс содержит два метода start и stop, полезные для настройки запуска и остановки пакета.

Еще одной особенностью пакета является его файл манифеста, вот часть файла манифеста org.eclipse.equinox.jsp.jasper:

Как мы видим, этот манифест содержит некоторую метаинформацию, необходимую контейнеру, например, указание класса активатора пакета, который реализует интерфейс BundleActivator.

Пакет представляет собой первую часть головоломки, и вот упрощенное представление пакета:

затмение7

И просто чтобы иметь представление обо всех бандлах, используемых eclipse, давайте найдем все классы, реализующие интерфейс BundleActivator.

затмение2

Кто управляет пакетом и вызывает методы BundleActivator?

Чтобы обнаружить это, давайте найдем методы, прямо или косвенно вызывающие BundleActivator.start.

затмение6

Пакет активируется платформой OSGi при запуске. Класс фреймворка запускается контейнером равноденствия. И чтобы лучше понять, что происходит при запуске контейнера, вот некоторые действия, выполняемые при запуске контейнера:

затмение31

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

Класс BundleHost реализует интерфейс Bundle, который содержит такие методы, как запуск, остановка, удаление и обновление. Эти методы необходимы для управления жизненным циклом пакета.

Итак, наша вторая часть головоломки — контейнер OSGi, он запускается с помощью Equinoxlauncher, который инициализирует фреймворк. Класс фреймворка отвечает за загрузку пакетов и их активацию.

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

Возьмем в качестве примера пакет org.eclipse.equinox.http.servlet и найдем методы, вызываемые методом запуска его класса Activator.

затмение1

Этот пакет создает службу и регистрирует ее в контейнере. Служба в OSGi определяется стандартным классом или интерфейсом Java. Обычно интерфейс Java используется для определения интерфейса службы. Служба является предпочтительным методом, который пакеты должны использовать для связи друг с другом.

Вот несколько полезных сценариев использования сервисов:

  • Экспорт функций из пакета в другие пакеты.
  • Импорт функций из других пакетов.
  • Зарегистрируйте прослушиватели для событий из других пакетов.

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

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

затмение8

Если пакет использует службы для связи с другими пакетами, как он взаимодействует с другими банками?

Если мы разработаем пакет и попытаемся использовать класс из другого jar, мы можем быть удивлены тем, что он не будет работать должным образом, причина в том, что ClassLoader перехватывается контейнером OSGi, чтобы проверить, что давайте искать, какой метод вызывает java. язык.Thread.setContextClassLoader.

затмение9

Его вызывают многие методы, включая EquinoxLauncher. поэтому каждый раз, когда пакет пытается создать экземпляр класса, контейнер OSGi будет проверять, разрешено ли коду выполнять это действие или нет, и здесь появляется роль импортированного и экспортированного пакета в файле манифеста.

Пакет объявляет явно экспортированный и импортированный пакет, и чтобы проверить это, давайте найдем пакеты, используемые пакетом org.eclipse.equinox.http.servlet, и проверим, использует ли он только импортированный пакет.

затмение10

Как мы видим, все используемые пакеты указаны в файле манифеста в разделе импорта пакетов.
Однако экспортированный пакет представляет собой пакет, который можно использовать из других пакетов. он представлен интерфейсом ExportedPackage, и мы можем искать классы контейнеров, используя этот интерфейс.

затмение12

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

Мы можем принудительно проверить использование импортированных пакетов с помощью других инструментов, например, с помощью CQLinq мы можем написать некоторые правила, предупреждающие каждый раз, когда проект использует пакеты, отличные от указанных, но лучше иметь эту проверку в среде выполнения, чтобы разработчик нельзя нарушать эти правила.

Эта возможность обрабатывать импортированные и экспортированные пакеты управляется уровнем модулей OSGi, и это была наша четвертая часть головоломки.

Давайте вернемся к контейнеру OSGi и выясним, какие сервисы он предоставляет?

Контейнерные услуги

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

затмение11

Некоторые классы уже обнаружены ранее, например BundleRepository, BundleHost, PackageAdminImpl и ServiceRegistry.

А как насчет других классов:

  • Начальный уровень менеджера:
    Каждый пакет OSGi связан с начальным уровнем, который позволяет серверу управлять относительным порядком запуска и остановки пакетов. Активными должны быть только пакеты, начальный уровень которых меньше или равен активному начальному уровню серверной платформы. Обычно пакет с меньшим начальным уровнем обычно запускается раньше.
  • БезопасностьАдминистратор:
    Уровень безопасности обрабатывает аспекты безопасности, ограничивая функциональность пакета заранее определенными возможностями.
  • Менеджер по корпоративным мероприятиям:
    Служба администратора событий предоставляет модель публикации-подписки для обработки событий. Это реализовано в соответствии со спецификацией службы администрирования событий OSGi. Служба администрирования событий распределяет события между издателями событий и подписчиками событий (обработчиками событий), вставляя канал событий. Издатели публикуют события в канале, а канал событий определяет, какие обработчики должны быть уведомлены. Таким образом, издатели и обработчики не имеют прямого знания друг о друге, что упрощает управление событиями.

Полная картина OSGi

Соберем все описанные ранее кусочки пазла, и у нас получится следующая OSGi-картинка:
расслоения-осги

Эта архитектура имеет следующие интересные преимущества:

  • Простой.
  • Уменьшенная сложность.
  • Простое развертывание.
  • Безопасный.

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