Здравствуйте, уважаемые читатели. Суровый челябинский программист снова здесь и готов продолжить серию статей, представляющих собой введение в замечательное средство построение модульных систем - OSGi.
В
прошлый раз мы с вами научились управлять жизненным циклом бандлов из консоли, а также познакомились со средствами Equinox, такими как org.eclipse.equinox.launcher.
Сегодня я предлагаю поговорить о взаимодействии бандлов. Сначала позволю себе немного пофилософствовать.
Понятно, что раз приложение многомодульное, то априори подразумевается какое-то взаимодействие этих самых модулей. И тут разумно поставить 2 вопроса: зачем и как? Ответ на вопрос "зачем" интуитивно понятен. Мы хотим, чтобы наше приложение было расширяемым, т.е. чтобы мы сами или сторонние разработчики могли изменять/наращивать его функционал. Здесь уместно ввести понятие "точка расширения". Точкой расширения (не в терминах Eclipse RCP, а в неком глобальном смысле) мы будем называть то место, в котором приложение позволяет нарастить свой функционал. Например, у нас есть главное меню приложения, в котором определены точки расширения для подменю и пунктов подменю. Это значит, что мы можем добавлять свои подменю, состоящие из пунктов меню. Но не можем, используя данные точки расширения, добавить новое окно. Переходя к бандлам видим, что концептуально здесь все просто: один бандл выставляет (публикует) некие точки расширения, а другой, подключаясь к ним, расширяет возможности первого бандла. Соответственно, третий бандл может еще больше расширить возможности первого и т.д.
Другим интересным вопросом является вопрос "как". Т.е. как определить точку расширения в одном бандле и как ее использовать в другом бандле?
OSGi предлагает несколько способов организации взаимодействия бандлов:
- Обмен ресурсами. Под ресурсами здесь подразумеваются java-классы, java-пэкеджи, библиотеки и другие файлы. В Eclipse RCP, например, самым распространенным способом определения точек расширения является их регистрация в файлах plugin.xml, впрочем, об этом мы еще поговорим.
- OSGi-сервисы. Собственно, OSGi и задумывалась, как среда выполнения и взаимодействия сервисов. Суть очень проста - один бандл выставляет сервисы, а другие их используют. Данный способ требует активации бандла, потому что выставление и подключение к сервисам, как правило, осуществляется в активаторе бандла. Активация бандла требует расходов на управление жизненным циклом бандлов, но в тоже время обеспечивает динамичность всей системы.
- Декларативные сервисы. Некое объединение преимуществ первого и второго способов. Сервисы описываются декларативно в xml-файлах и становятся видимыми другим бандлам. При первом использовании сервиса стартует активатор бандла, сервис становится работоспособным и доступным для использования.
- Регистрация событий и их обработчиков. В общем - стандартная событийная модель. Одни бандлы регистрируют события, а другие подписываются на эти события. Соответственно при возникновении нужного события в одном бандле срабатывает его обработчик из другого.