Interacțiunile dintre benzi

Un sistem modular care suportă doar dependențe statice este fragil și nu poate suporta extensibilitatea. Fragilitatea înseamnă că nu puteți șterge niciun modul fără a perturba performanța (compilarea, asamblarea) aplicației în ansamblu. Lipsa extensibilității înseamnă că nu puteți adăuga un nou modul de funcții în sistem fără a recompila sistemul existent.







Una dintre cele mai importante sarcini ale programării orientate pe obiecte este creșterea flexibilității și reutilizarea codului prin reducerea conexiunii dintre furnizorii unei anumite funcționalități și utilizatorii acestei funcționalități. În Java, acest lucru se realizează prin utilizarea interfețelor. care sunt clase pur abstracte care descriu funcționalitatea sub forma unei liste definitive de metode ale altor clase care le implementează. Interfețele și clasele abstracte pot fi folosite ca trimiteri la un obiect specific cu legare târzie pentru a construi un sistem modular.

Link-uri târzii

OSGi rezolvă problema legării târzii folosind servicii dinamice, care se bazează pe principiul injecției de dependență (DI), procesul de furnizare a dependenței externe de o componentă software. DI este o formă specifică de "Inversiune de control (IoC), atunci când este aplicată gestionării dependențelor. În acest caz, obiectul (pachetul) își schimbă responsabilitatea pentru a construi dependențele necesare unei entități externe, special concepută pentru acest mecanism comun. Trebuie reținut faptul că în specificația OSGi funcționează cu așa-numitele pachete. În textul articolului, împreună cu benzile, se poate găsi o astfel de entitate ca și plug-in, sensul căruia îi atribuim sinonimului.

Figura următoare ilustrează interacțiunea benzilor într-un container OSGi care utilizează serviciile.

Interacțiunile dintre benzi

Bundle-ul furnizorului de servicii trebuie să fie înregistrat ca serviciu (Registru) în registrul de containere OSGi. Restul clientului poate obține un "link" la el. După aceea, este necesar să contactați serviciul (Bind) și să utilizați serviciile acestuia (metode).

Aici ar trebui să fim atenți la particularitățile utilizării acestei scheme de interacțiune:

  • Serviciul de pachete trebuie înregistrat în fața clientului pachet;
  • Un client pachet trebuie să fie conștient de existența unui serviciu specific de pachete în registru.

Dacă serviciul de pachete este independent de alte servicii, dezvoltarea lui este simplificată. este necesar să definiți în mod corespunzător structura și metodele, apoi să le instalați în containerul OSGi și să vă înregistrați ca un serviciu. Dar, cu clientul pachetului, sarcina este un pic mai complicată, deoarece deja trebuie să utilizați metodele de pachet-service atunci când se dezvoltă. Să vedem cum va arăta acest lucru într-un exemplu.

Un exemplu de utilizare a serviciului OSGi pentru interacțiunea benzilor

Luați în considerare un exemplu de interacțiune a două benzi. Un pachet (serviciu) va furniza o listă de valute și un alt pachet (client) se va conecta la serviciu, va primi o listă de valute și va afișa în consola. În timpul dezvoltării vor fi create două proiecte:

  • serviciu-valută. serviciu care oferă o listă de valute;
  • pachet-schimb. utilizarea de către client a serviciului.

Descrierea pachetului conform specificației OSGi și a diferenței sale față de fișierul obișnuit de jar este descris în detaliu aici.

Descrierea serviciului valutar al proiectului

Structura serviciului-valută include interfața ICurrency.java, implementarea CurrencyImpl.java și activatorul CurrencyActivator.java.

Afișați interfața ICurrency.java

Interfața include o metodă, getName (). care returnează numele serviciului.

Afișarea clasei CurrencyImpl.java

Clasa CurrencyImpl implementează metoda getName () a ICN și include în plus metoda methodCurrencies (). care returnează o listă de valute ca o serie de șiruri de caractere.

Afișarea activatorului serviciului CurrencyActivator.java

serviciul Activator la start (metoda start) primește ca parametru contextul unui context de tip container BundleContext, care înregistrează serviciul prin apelarea metodei context registerService. Metoda registerService returnează un obiect de tip ServiceRegistration. care se utilizează atunci când serviciul este oprit în metoda de oprire. Ca parametri pentru înregistrarea serviciului în registerService metodei transmise numele serviciului (clasa), precum și un exemplu de proprietăți de servicii. Nu puteți defini proprietăți ale serviciului, atunci trebuie să treceți nul la metodă.







În metoda de oprire, resursele de serviciu (pachet) sunt eliberate și înregistrarea serviciului este anulată apelând metoda de neînregistrare din clasa ServiceRegistration.

Descrierea asamblării pom.xml

Pentru a construi proiectul de modificare a serviciului, utilizați pom.xml după cum urmează:

În fișierul de descriere al asamblării pom.xml, dependența cadrului osgi (secțiunea ) și parametrii pachetului pentru formarea manifestului META-INF / MANIFEST.MF. Ca rezultat al asamblării, un pachet va fi creat în subdirectorul de proiect țintă sub forma unui serviciu de fișiere-currency-1.0.0.jar cu următorul manifest:

Instalarea și înregistrarea serviciului

Pentru a testa serviciul creat, folosim folderul inclus în arhiva exemplului , în care org.eclipse.osgi_ХХХ.jar este localizat pentru a crea un container Equinox. Puteți citi comenzile din container aici. Rulați containerul Equinox, instalați serviciul pachet în container și porniți-l:

În procesul de testare a pachetului de servicii, îl conducem în toate etapele ciclului de viață executând comenzile install, start, stop. Folosind comanda de servicii cu parametrul corespunzător, consola a afișat informații despre serviciu:

  • folosit ca o clasă de servicii com.osgi.service.CurrencyImpl;
  • rezervele de proprietate (serviciu = valută), determinate la înregistrare;
  • numărul de identificare al serviciului, în cazul nostru service.id = 29;
  • care a înregistrat serviciul;
  • lipsa benzilor conectate.

Dacă apelați comanda de servicii fără parametri, puteți vedea întreaga listă de servicii încărcate de containerul Equinox.

Astfel, putem concluziona că serviciul a fost descărcat și înregistrat cu succes în sistem, dar nimeni nu este conectat la acesta.

Descrierea proiectului de schimb de pachete

Structura plug-in de schimb de pachete include interfața IExchange.java, implementarea ExchangeImpl.java și activatorul ExchangeActivator.java.

Afișați interfața IExchange.java

Interfața include o metodă, getCurrencies (). care returnează o listă a valorilor textului.

Afișarea clasei ExchangeImpl.java

Când accesați serviciul în metoda getCurrencies (), acesta verifică pentru null. Dacă serviciul nu este găsit, metoda returnează o listă goală. Acest lucru se poate datora faptului că serviciul poate fi absent sau nu poate fi înregistrat în sistem. În acest caz, pentru a încerca să obțineți serviciul, ServiceTracker ne va returna.

Clasa de utilități OSGi ServiceTracker este trecută ca parametru pentru constructor și este utilizată pentru a obține serviciul înregistrat în sistem.

Cu ServiceTracker puteți:
- să creeze o listă inițială a acestor servicii;
- urmărirea evenimentelor de evenimente pentru aceste servicii;
- permiteți proprietarului listei să o modifice programabil, precum și să efectueze orice acțiune în momentul adăugării sau eliminării serviciului în listă.

Constructori de obiecte ServiceTracker

Fiecare constructor ia un parametru BundleContext. Primul constructor este folosit pentru a obține numele interfeței de serviciu ca termen de căutare. Al doilea constructor este utilizat pentru a urmări toate serviciile care se încadrează în filtrul specificat. Cel de-al treilea constructor ia ca argument argumentul ServiceReference. care vă permite să urmăriți un anumit serviciu.

După ce a fost creat ServiceTracker, acesta începe să urmărească serviciile și vă permite să utilizați următoarele metode:

  • getService () / getServices () - serviciul de urmărire a traficului urmărit;
  • getServiceReference () / getServiceReferences () - metoda vă permite să apelați așteaptă atât de mult, până când cel puțin o instanță a unui serviciu de control sau înainte de expirarea timeout-ului.

Notă. nu este recomandat pentru utilizare getServiceReference () / getServiceReferences () în pachetul activator, așa cum se presupune că pachetul activatori trebuie să se încarce rapid, iar cadrul poate suspenda executarea activator la pachetul de descărcare care încarcă serviciul necesar, ceea ce ar putea duce la un impas în, în cazul în care serviciul nu este Acesta va fi încărcat.

Afișarea activatorului ExchangeActivator.java

Pentru a crea un tracker la pornirea constructorului ServiceTracker, al doilea parametru este numele serviciului. După aceea, tracker-ul se deschide, se creează o instanță a pachetului și în consoană este afișată o listă de valute. În metoda de oprire, împreună cu banda, tracker-ul se închide, de asemenea.

Descrierea asamblării pom.xml

În fișierul descriptiv al pom.xml de asamblare, plug-in-ul depinde de artefactul valută de serviciu pentru timpul de dezvoltare (furnizat), care este necesar pentru compilarea și crearea pachetului. Pentru ca maven să găsească acest artefact în repozitoriu, este necesar să executați comanda mvn install în serviciul precedent de monedă a serviciului. care va descărca artefactul în depozit.

Ca rezultat al asamblării în subdirectorul de proiect țintă, un pachet va fi creat ca un pachet-bundle-exchange-1.0.0.jar cu un manifest conținând următorul conținut:

testarea

După cum sa menționat mai sus, în fișierul model inclus «osgi.container» dosarul în care pentru a genera localizat org.eclipse.osgi_HHH.jar Equinox container. Pentru a descărca automat plug-in-uri (pachete) trebuie să fie plasate în subdirectorul «osgi.container / pachete», și în subdirectorul «osgi.container / configurația» config.ini pentru a personaliza fișierul de inițializare. După aceasta, pachetele vor fi încărcate automat în container, serviciul va fi înregistrat și clientul se va conecta la acesta. Și în consola vom vedea următoarea "imagine":

Este posibil să spunem că sarcina a fost rezolvată, iar benzile s-au "găsit reciproc" în spațiile containerului Equinox.

Descărcați codul sursă

Codurile sursă pentru interacțiunea exemplului pachet pentru platforma OSGi ca proiecte Eclipse pot fi descărcate aici (1,2 MB). Directorul osgi.container este, de asemenea, inclus în arhiva proiectului pentru a crea containerul Equinox și pentru a testa interacțiunea benzilor.







Trimiteți-le prietenilor: