OSGi — это способ определения динамического модуля в Java. Существует три основных контейнера OSGi, реализованных для Java, такие как Apache Felix , Eclipse Equinox и Knopflefish .
Почему ОСГи? Потому что OSGi предоставляет возможность разделить приложение на несколько модулей, и этим модулем легко управлять с другими зависимостями. кроме этого очень легко установить, обновить, остановить и удалить модуль без остановки механизма (например, контейнер веб-приложения Tomcat). Мы можем иметь несколько вариантов реализации с использованием других ссылок.
В веб-структуре Java есть три основных уровня (презентация, бизнес-уровень и уровень DAO). Там мы можем разделить его на три модуля на основе OSGi. тогда мы можем очень легко исправить ошибку в одном слое, не затрагивая другие и перезапустив наш веб-контейнер. Просто нам нужно обновить модуль.
в мире OSGi вывод является связкой, это может быть файл Jar или War. Пакет состоит из классов Java и других ресурсов с некоторыми дополнительными метаданными (предоставление услуг и пакетов другим пакетам).
Я собираюсь использовать Eclipse IDE для создания моего первого пакета. Потому что Eclipse IDe имеет встроенный контейнер Equinox (каждый плагин eclipse является пакетом OSGi).
Создать Eclipse Plug-In-Project
- Перейдите в New–> Other-> Plug-In-Project и нажмите Next, после чего появится диалог создания нового проекта.
- Укажите название проекта и целевую платформу, как показано ниже. и нажмите Далее
Название проекта: com.chandana.Hello.HelloWorld
Целевая платформа: выберите Stranded OSGi
- На следующем экране вы можете изменить информацию о пакете (эти данные доступны в MANIFEST.MF, а я предоставлю подробную информацию позже), затем нажмите кнопку Далее.
- После этого появится диалоговое окно выбора шаблона проекта OSGi. Выберите Hello OSGi Bundle и нажмите Finish.
Через несколько секунд Eclipse сгенерирует подключаемый проект Hello World (несколько секунд я не отвечал :))
В моем проекте структура выглядит так:
Activator.java
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
package com.chandana.hello.helloworld; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; public class Activator implements BundleActivator { /* * (non-Javadoc) * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext) */ public void start(BundleContext context) throws Exception { System.out.println( "Hello World!!" ); } /* * (non-Javadoc) * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) */ public void stop(BundleContext context) throws Exception { System.out.println( "Goodbye World!!" ); } } |
Activator — это класс, который реализует BundleActivator интерфейс. Он остановился и начать методы. Эти методы вызываются, когда пакет запускается или останавливается . Этот класс активатора пакета указывается в файле MENIFEST.MF (запись Bundle-Activator ).
Метод запуска:
Контейнер OSGi вызывает метод start при запуске bundle. Мы можем использовать этот метод запуска для инициализированного подключения к базе данных, зарегистрировать сервис для другого использования пакета.
Остановить метод:
Контейнер OSGi вызывает метод stop при остановке пакета. Мы можем использовать этот метод для удаления служб из реестра служб, таких как процесс очистки
MANIFEST.MF
1
2
3
4
5
6
7
8
9
|
Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: HelloWorld Bundle-SymbolicName: com.chandana.Hello.HelloWorld Bundle-Version: 1.0.0.qualifier Bundle-Activator: com.chandana.hello.helloworld.Activator Bundle-Vendor: CHANDANA Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Import-Package: org.osgi.framework;version= "1.3.0" |
Bundle-ManifestVersion
Заголовок Bundle-ManifestVersion показывает контейнеру OSGi, что этот пакет соответствует правилам спецификации OSGi. Значение 2 означает, что пакет соответствует спецификации OSGi версии 4; значение 1 означает, что оно соответствует версии 3 или более ранней.
Bundle-Name
Заголовок Bundle-Name определяет краткое читаемое имя для bundle.
Bundle-Символическое
Заголовок Bundle-SymbolicName указывает уникальное имя для пакета. Это имя, которое вы будете использовать при обращении к данному пакету из других пакетов.
Bundle-Version
Заголовок Bundle-Version — это номер версии пакета.
Bundle-Vendor
Заголовок Bundle-Vendor — это описание поставщика (например, мое имя).
Импорт-пакет
Import-Package указывает, какие другие Java-пакеты (OSGi) необходимы для этого пакета. что мы называли зависимостью.
Экспорт-пакет
Export-Package указывает, что являются открытыми пакетами в комплекте, и эти Export-Package могут импортировать из другого пакета.
Запустите Bundle:
- Для запуска этого проекта нажмите «Выполнить» -> «Выполнить настройку», в OSGi Framework щелкните правой кнопкой мыши и создайте новую конфигурацию «Выполнить».
- Сначала снимите флажок со всей целевой платформы и нажмите « Добавить необходимые комплекты» .
- После этого примените изменения и запустите проект, нажав кнопку «Выполнить».
- После запуска проекта консоль OSGi отобразится как показано ниже.
Команды терминала OSGi:
Далее я опишу, как создать пакет OSGi на основе зависимостей.
Служба OSGi — это экземпляр объекта Java, который зарегистрирован в платформе OSGi с набором атрибутов. Доступ к сервисам осуществляется через реестр сервисов (выполняется через класс BundleContext). BundleActivator должен вызываться при запуске и остановке. Когда BundleActivator вызывает метод start, мы собираемся зарегистрировать наш сервис. После этого любой пакет может получить доступ к этой услуге.
Пакет услуг:
В комплекте услуг вы должны экспортировать свой сервис и зарегистрировать его через реестр сервисов. Когда мы экспортируем сервис, мы экспортируем только интерфейсный пакет. Как обычно это скрыть реализацию от других пакетов.
Я создал пример проекта OSGi под названием HelloService
MANIFEST.MF
01
02
03
04
05
06
07
08
09
10
11
|
Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: HelloService Bundle-SymbolicName: com.chandana.hello.HelloService Bundle-Version: 1.0.0 Bundle-Activator: com.chandana.hello.helloservice.Activator Bundle-Vendor: CHANDANA Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Import-Package: org.osgi.framework;version= "1.3.0" Export-Package: com.chandana.hello.service Bundle-ActivationPolicy: lazy |
Сервисный интерфейс:
1
2
3
|
public interface HelloService { public String helloMethods(); } |
Внедрение сервиса:
1
2
3
4
5
6
7
|
public class HelloServiceImpl implements HelloService { @Override public String helloMethods() { String retValue = "Inside Hello Service method" ; return retValue; } } |
Активатор Boundle:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
|
public class Activator implements BundleActivator { ServiceRegistration serviceRegistration; /* * (non-Javadoc) * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext) */ public void start(BundleContext context) throws Exception { System.out.println( "Bundle Started.....!!!!!" ); HelloService service = new HelloServiceImpl(); serviceRegistration = context.registerService(HelloService. class .getName(), service, null ); } /* * (non-Javadoc) * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) */ public void stop(BundleContext context) throws Exception { System.out.println( "Bundle Stoped.....!!!!!" ); serviceRegistration.unregister(); } } |
Когда мы используем опубликованные сервисы, мы можем импортировать их из другого комплекта. Поэтому нужно создать еще один плагин-проект для HelloClient
Контекст связки
Контекст пакета — это контекст одного пакета в среде выполнения OSGi, который создается при запуске пакета. Контекст пакета можно использовать для установки новых пакетов, получения зарегистрированных служб другими пакетами и регистрации служб в рамках.
MANIFEST.MF
1
|
Import-Package: org.osgi.framework;version= "1.3.0" ,com.chandana.hello.service |
После импорта пакета вы можете получить доступ к услуге. Важно то, что сервис доступен только через контекст пакета. Вы можете получить фактический объект службы с помощью метода BundleContext.getService ().
Класс активатора:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
|
public class Activator implements BundleActivator { ServiceReference serviceReference; /* * (non-Javadoc) * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext) */ public void start(BundleContext context) throws Exception { serviceReference= context.getServiceReference(HelloService. class .getName()); HelloService helloService =(HelloService)context.getService(serviceReference); System.out.println(helloService.helloMethods()); } /* * (non-Javadoc) * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) */ public void stop(BundleContext context) throws Exception { context.ungetService(serviceReference); } } |
Метод context.getServiceReference () возвращает ссылку на сервис OSGi HelloService, и с помощью этой ссылки на сервис можно получить доступ к реальному объекту сервиса.
Для запуска этого проекта нажмите « Выполнить» -> «Выполнить настройку» , в OSGi Framework щелкните правой кнопкой мыши и создайте новую конфигурацию «Выполнить» . Убедитесь, что HelloService и HelloClient .
Вопросы :
Что произошло, если служба не запущена, когда клиент обращается к ней?
Что случилось, если вы остановили пакет услуг?
Код Репо :
http://code.google.com/p/osgi-world/source/browse/#svn/trunk/com.chandana.hello.HelloService
http://code.google.com/p/osgi-world/source/browse/#svn/trunk/com.chandana.hello.HelloClient
Ссылка: Введение в OSGi (Java Modular) и Введение в OSGi — 2 (OSGi Services) от нашего партнера JCG Чандана