Zrozum pojęcia OSGi. Spróbuj podążać za łamigłówką

Opublikowany: 2013-04-20

OSGi stało się dziś bardzo popularne dzięki swojemu modułowemu podejściu i możliwości narzucania logicznych granic między modułami. Kiedy odkrywamy to po raz pierwszy, pojawia się pytanie, od czego zacząć rozumieć, jak to działa?

Aby zrozumieć koncepcje OSGi, postaramy się zastosować podejście zagadkowe, chodzi o rozpoczęcie od trywialnej części tej technologii i poszukiwanie innych części powiązanych z tymi znalezionymi. W ułożeniu puzzli pomoże nam JArchitect, który będzie pomocny w wykrywaniu wewnętrznego projektu OSGi.

Aby być bardziej konkretnym, analizujemy za pomocą JArchitect aplikację korzystającą z technologii OSGi, dotyczy ona słynnego środowiska eclipse IDE, które wykorzystuje równonoc kontenera OSGi.

Zacznijmy od typowej definicji OSGi:

OSGi zmniejsza złożoność, zapewniając modułową architekturę dzisiejszym wielkoskalowym systemom rozproszonym, a także małym aplikacjom wbudowanym. Budowanie systemów z własnych i gotowych modułów znacznie zmniejsza złożoność, a tym samym koszty rozwoju i utrzymania. Model programowania OSGi realizuje obietnicę systemów opartych na komponentach.

Trywialną częścią OSGi jest modułowość, zobaczmy, czym są moduły OSGi?

Moduły OSGI nazywane są Bundles i dlatego każda aplikacja składa się z przynajmniej jednego pakietu.
Te pakiety są wykonywane wewnątrz kontenera, a ponieważ każde podejście modułowe, w którym kontener zarządza modułami, pytanie brzmi, która umowa musi implementować każdy moduł, aby był zintegrowany z kontenerem?

Weźmy jako przykład pakiet org.eclipse.equinox.jsp.jasper i wyszukajmy wszystkie jego zaimplementowane interfejsy, w tym celu możemy wykonać następujące żądanie CQLinq:

zaćmienie4

Zaimplementowano interfejs BundleActivator z pakietu OSGi, który zawiera dwie metody start i stop, przydatne do dostosowania uruchamiania i zatrzymywania pakietu.

Inną specyfiką pakietu jest jego plik manifestu, oto część z pliku manifestu org.eclipse.equinox.jsp.jasper:

Jak widać, ten manifest zawiera pewne metainformacje potrzebne kontenerowi, takie jak określenie klasy aktywatora pakietu, która implementuje interfejs BundleActivator.

Paczka reprezentuje nasz pierwszy element układanki, a oto uproszczona reprezentacja paczki:

zaćmienie7

Aby mieć pojęcie o wszystkich pakietach używanych przez eclipse, poszukajmy wszystkich klas implementujących interfejs BundleActivator.

zaćmienie2

Kto zarządza pakietem i może wywoływać metody BundleActivator?

Aby to odkryć, poszukajmy metod wywołujących bezpośrednio lub pośrednio BundleActivator.start

zaćmienie6

Pakiet jest aktywowany przez framework OSGi w momencie jego uruchomienia. Klasa frameworka jest uruchamiana przez kontener równonocy. Aby lepiej zrozumieć, co się dzieje po uruchomieniu kontenera, oto kilka akcji wykonywanych po uruchomieniu kontenera:

zaćmienie31

Po uruchomieniu kontenera inicjuje on framework OSGi, framework pobiera wszystkie zainstalowane pakiety i dla każdego z nich tworzy instancję klasy BundleHost i przechowuje znaleziony pakiet w repozytorium.

Klasa BundleHost implementuje interfejs Bundle, który zawiera metody takie jak start, stop, odinstalowywanie i aktualizacja, metody te są potrzebne do zarządzania cyklem życia pakietu.

Więc naszym drugim elementem układanki jest kontener OSGi, uruchamiany przez Equinoxlauncher, który inicjuje framework. Klasa framework odpowiada za ładowanie paczek i ich aktywację.

Po odkryciu podstawowych pojęć dotyczących pakietu i kontenera zajrzyjmy głęboko do pakietów i odkryjmy, jak działają wewnętrznie.

Weźmy jako przykład pakiet org.eclipse.equinox.http.servlet i poszukajmy metod wywoływanych przez metodę start jej klasy Activator.

zaćmienie1

Ten pakiet tworzy usługę i rejestruje ją w kontenerze. Usługa w OSGi jest zdefiniowana przez standardową klasę lub interfejs Java. Zazwyczaj interfejs Java jest używany do definiowania interfejsu usługi. Usługa jest preferowaną metodą, której pakiety powinny używać do komunikowania się między sobą.

Oto kilka przydatnych scenariuszy korzystania z usług:

  • Eksportuj funkcjonalność z pakietu do innych pakietów.
  • Importuj funkcjonalność z innych pakietów.
  • Zarejestruj detektory wydarzeń z innych pakietów.

Kolejną uwagą z poprzedniego wykresu zależności jest to, że do utworzenia wystąpienia usługi używana jest fabryka usług.

Naszym trzecim elementem układanki jest warstwa usług OSGi, każdy pakiet może używać lub deklarować jakieś usługi, co wymusza podejście do projektowania komponentów, oto nowa reprezentacja pakietu OSGi.

zaćmienie8

Jeśli pakiet używa usług do komunikacji z innymi pakietami, w jaki sposób komunikuje się z innymi plikami JAR?

Jeśli opracujemy pakiet i spróbujemy użyć klasy z innego jara, możemy się zdziwić, że nie zadziała zgodnie z oczekiwaniami, powodem jest to, że ClassLoader jest podpięty przez kontener OSGi, aby sprawdzić, czy przeszukajmy, która metoda wywołuje java. lang.Thread.setContextClassLoader.

zaćmienie9

Wywołuje go wiele metod, w tym EquinoxLauncher. więc za każdym razem, gdy paczka próbuje utworzyć instancję klasy, kontener OSGi sprawdzi, czy kod może wykonać tę akcję, czy nie, i tutaj pojawia się rola importowanego i eksportowanego pakietu w pliku manifestu.

Pakiet deklaruje jawnie wyeksportowany i zaimportowany pakiet. Aby to sprawdzić, wyszukajmy pakiety używane przez pakiet org.eclipse.equinox.http.servlet i sprawdź, czy używa on tylko pakietu importowanego.

zaćmienie10

Jak widać, wszystkie użyte pakiety są wyszczególnione w pliku manifestu, w sekcji importu pakietów.
Wyeksportowany pakiet reprezentuje jednak pakiet, którego można użyć z innych pakietów. jest reprezentowany przez interfejs ExportedPackage i możemy wyszukiwać klasy kontenerów za pomocą tego interfejsu.

zaćmienie12

Interesujące w przypadku tej nowej możliwości jest to, że pakiet będzie miał dobrze zdefiniowaną granicę, a to, czego używa i co udostępnia jako usługi, jest bardzo dobrze określone.

Sprawdzenie wykorzystania importowanych pakietów możemy wymusić za pomocą innych narzędzi, np. za pomocą CQLinq możemy napisać pewne reguły ostrzegające za każdym razem, gdy projekt używa innych pakietów niż określone, ale lepiej mieć taką kontrolę w środowisku wykonawczym, więc deweloper nie może łamać tych zasad.

Ta zdolność do przetwarzania importowanych i eksportowanych pakietów jest zarządzana przez warstwę modułów OSGi i był to nasz czwarty element układanki.

Wróćmy do kontenera OSGi i zobaczmy, jakie usługi świadczy?

Usługi kontenerowe

Jak odkryliśmy przed uruchomieniem kontenera przez klasę EquinoxLauncher, a klasa frameworka inicjuje i uruchamia pakiety, aby wykryć, które usługi są dostarczane, przeszukajmy wszystkie klasy użyte w metodzie inicjalizacji frameworka.

zaćmienie11

Niektóre klasy zostały już wcześniej odkryte, takie jak BundleRepository, BundleHost,PackageAdminImpl i ServiceRegistry.

A co z innymi klasami:

  • StartLevelManager:
    Każdy pakiet OSGi jest powiązany z poziomem uruchamiania, który umożliwia serwerowi kontrolowanie względnej kolejności uruchamiania i zatrzymywania pakietów. Tylko pakiety, których poziom początkowy jest mniejszy lub równy aktywnemu poziomowi początkowemu struktury serwera, muszą być aktywne. Zazwyczaj pakiet o niższym poziomie początkowym zaczyna się wcześniej.
  • Administrator zabezpieczeń:
    Warstwa bezpieczeństwa obsługuje aspekty bezpieczeństwa, ograniczając funkcjonalność pakietu do wstępnie zdefiniowanych możliwości.
  • Menedżer zdarzeń:
    Usługa Administrowanie zdarzeniami udostępnia model publikowania-subskrypcji do obsługi zdarzeń. Jest ona realizowana zgodnie ze Specyfikacją usług administratora zdarzeń OSGi. Usługa Administrowanie zdarzeniami wysyła zdarzenia między wydawcami zdarzeń a subskrybentami zdarzeń (obsługi obsługi zdarzeń) przez wprowadzenie kanału zdarzeń. Wydawcy publikują zdarzenia w kanale, a kanał zdarzeń określa, które programy obsługi muszą zostać powiadomione. W związku z tym wydawcy i osoby zajmujące się obsługą nie mają o sobie bezpośredniej wiedzy, co upraszcza zarządzanie zdarzeniami.

Cały obraz OSGi

Złóżmy wszystkie opisane wcześniej elementy układanki, a otrzymamy następujący obrazek OSGi:
warstw-osgi

Ta architektura ma następujące interesujące zalety:

  • Prosty.
  • Zmniejszona złożoność.
  • Łatwe wdrażanie.
  • Bezpieczne.

Co sprawia, że ​​jest to bardzo atrakcyjne i warte objazdu, a nie będziesz tracić czasu, jeśli przestudiujesz go dogłębnie.