OSGi Kavramlarını Anlayın. Bulmaca Yaklaşımını İzlemeye Çalışın
Yayınlanan: 2013-04-20OSGi
, modülerlik yaklaşımı ve modüller arasında mantıksal sınırları zorlama yeteneği sayesinde bugün çok popüler hale geldi. Onu ilk kez keşfettiğimizde soru, nasıl çalıştığını anlamaya nereden başlayacağımızdır.
OSGi kavramlarını anlamak için bulmaca yaklaşımını izlemeye çalışacağız, fikir bu teknolojinin önemsiz kısmıyla başlamak ve bulunanlarla ilgili diğer parçaları aramaktır. Ve bulmacayı birleştirmek için, OSGi iç tasarımını tespit etmeye yardımcı olacak JArchitect tarafından destekleneceğiz.
Daha somut olmak için JArchitect ile OSGi teknolojisini kullanan bir uygulamayı analiz ediyoruz, OSGi kapsayıcı ekinoksunu kullanan ünlü tutulma IDE'si ile ilgili.
Tipik OSGi tanımıyla başlayalım:
OSGi, günümüzün büyük ölçekli dağıtılmış sistemleri ve ayrıca küçük, gömülü uygulamalar için modüler bir mimari sağlayarak karmaşıklığı azaltır. Şirket içi ve kullanıma hazır modüllerden sistemler oluşturmak, karmaşıklığı ve dolayısıyla geliştirme ve bakım masraflarını önemli ölçüde azaltır. OSGi programlama modeli, bileşen tabanlı sistemlerin vaadini gerçekleştirir.
OSGi'nin önemsiz kısmı modülerliktir, hadi OSGi modüllerinin ne olduğunu keşfedelim?
OSGI modüllerine Paketler denir ve bu nedenle her uygulama en az bir paketten oluşur.
Bu paketler bir kapsayıcı içinde yürütülür ve bir kapsayıcının modülleri yönettiği her modüler yaklaşım olarak, soru, kapsayıcıya entegre edilecek her modülü hangi sözleşmenin uygulaması gerektiğidir?
Örnek olarak org.eclipse.equinox.jsp.jasper paketini alalım ve uygulanan tüm arayüzlerini arayalım, bunun için aşağıdaki CQLinq isteğini gerçekleştirebiliriz:
1 2 3 4 |
from t in Types where t . ParentProject . Name ==” org . eclipse . equinox . jsp . jasper_1 . 0.300.v20110502 “ let interfaces = t . InterfacesImplemented from i in interfaces select i |
OSGi paketinden BundleActivator arabirimi uygulanır, bu arabirim paketin başlatılmasını ve durdurulmasını özelleştirmek için yararlı olan iki başlatma ve durdurma yöntemini içerir.
Bir paketin diğer bir özelliği de bildirim dosyasıdır, işte org.eclipse.equinox.jsp.jasper bildirim dosyasından bir bölüm:
1 2 3 4 5 6 7 8 9 |
Manifest - Version : 1.0 Bundle - Localization : plugin Bundle - RequiredExecutionEnvironment : CDC - 1.0 / Foundation - 1.0 , J2SE - 1.3 Bundle - SymbolicName : org . eclipse . equinox . jsp . jasper Eclipse - LazyStart : true Eclipse - SourceReferences : scm : cvs : pserver : dev . eclipse . org : / cvsroot / rt : org . eclipse . equinox / server - side / bundles / org . eclipse . equinox . jsp . jaspe r ; tag = v20110502 Bundle - Activator : org . eclipse . equinox . internal . jsp . jasper . Activator |
Gördüğümüz gibi, bu bildirim, BundleActivator arabirimini uygulayan paket etkinleştirici sınıfını belirtmek gibi kap tarafından ihtiyaç duyulan bazı meta bilgileri içerir.
Paket, bulmacanın ilk parçasını temsil ediyor ve işte bir paketin basitleştirilmiş bir temsili:
Eclipse tarafından kullanılan tüm paketler hakkında fikir sahibi olmak için, BundleActivator arabirimini uygulayan tüm sınıfları arayalım.
1 2 |
from t in Types where t . Implement ( “ org . osgi . framework . BundleActivator “ ) select new { t , t . NbBCInstructions } |
Paketi kim yönetiyor ve BundleActivator yöntemlerini çağırıyor?
Bunu keşfetmek için, doğrudan veya dolaylı olarak BundleActivator.start'ı çağıran yöntemleri arayalım.
1 2 3 4 |
from m in Methods let depth0 = m . DepthOfIsUsing ( “ org . eclipse . osgi . framework . internal . core . BundleContextImpl . startActivator ( BundleActivator ) “ ) where depth0 > = 0 orderby depth0 select new { m , depth0 } |
Paket, başlatıldığında OSGi çerçevesi tarafından etkinleştirilir. Çerçeve sınıfı, ekinoks kabı tarafından başlatılır. Kapsayıcı başladığında ne olduğunu daha iyi anlamak için, kapsayıcı başlatıldığında yürütülen bazı eylemler şunlardır:
Kapsayıcı başlatıldığında, OSGi çerçevesini başlatır, çerçeve kurulu tüm paketleri alır ve her biri için bir BundleHost sınıfı örneği oluşturur ve bulunan paketi bir havuzda depolar.
BundleHost sınıfı, başlatma, durdurma, kaldırma ve güncelleme gibi yöntemleri içeren Bundle arabirimini uygular, bu yöntemler paket yaşam döngüsünü yönetmek için gereklidir.
İkinci yapboz parçamız OSGi kabıdır, çerçeveyi başlatan Equinoxlauncher tarafından başlatılır. Çerçeve sınıfı, paketlerin yüklenmesinden sorumludur ve bunları etkinleştirir.
Paket ve kapsayıcı ile ilgili bazı temel kavramları keşfettikten sonra, paketlerin derinliklerine inelim ve bunların dahili olarak nasıl çalıştıklarını keşfedelim.
Örnek olarak org.eclipse.equinox.http.servlet paketini alalım ve Activator sınıfının start yöntemi tarafından çağrılan yöntemleri arayalım.
Bu paket bir hizmet oluşturur ve onu kapsayıcıya kaydeder. OSGi'deki bir hizmet, standart bir Java sınıfı veya arabirimi tarafından tanımlanır. Hizmet arabirimini tanımlamak için tipik olarak bir Java arabirimi kullanılır. Hizmet, paketlerin kendi aralarında iletişim kurmak için kullanması gereken tercih edilen yöntemdir.

Hizmetleri kullanmanın bazı yararlı senaryoları şunlardır:
- İşlevselliği bir paketten diğer paketlere aktarın.
- Diğer paketlerden işlevselliği içe aktarın.
- Diğer paketlerdeki etkinlikler için dinleyicileri kaydedin.
Önceki bağımlılık grafiğinden başka bir açıklama, hizmet örneğini oluşturmak için bir hizmet fabrikasının kullanılmasıdır.
Bulmacanın üçüncü parçamız OSGi hizmetleri katmanıdır, her paket bazı hizmetleri kullanabilir veya bildirebilir, bileşen tasarım yaklaşımını zorlayan şey, işte OSGi paketinin yeni temsili.
Paket, diğer paketlerle iletişim kurmak için hizmetleri kullanıyorsa, diğer kavanozlarla nasıl iletişim kurar?
Bir paket geliştirir ve başka bir kavanozdan bir sınıf kullanmaya çalışırsak, beklendiği gibi çalışmamasına şaşırabiliriz, bunun nedeni ClassLoader'ın OSGi konteynerine bağlanmasıdır, hangi yöntemin java'yı çağırdığını kontrol edelim. lang.Thread.setContextClassLoader.
1 2 |
from m in Methods where m . IsUsing ( “ java . lang . Thread . setContextClassLoader ( ClassLoader ) “ ) select new { m , m . NbBCInstructions } |
EquinoxLauncher dahil birçok yöntem onu çağırır. bu nedenle, paket her sınıf örneği oluşturmaya çalıştığında, OSGi kapsayıcısı, kodun bu eylemi yapmasına izin verilip verilmediğini kontrol eder ve işte burada, manifest dosyasında içe ve dışa aktarılan paketin rolü gelir.
1 2 3 4 |
Export - Package : org . eclipse . equinox . http . servlet ; version =” 1.1.0 ″ Import - Package : javax . servlet ; version =” 2.3 ″ , javax . servlet . http ; version =” 2.3 ″ , org . osgi . framework ; version =” 1.3.0 ″ , org . osgi . service . http ; versi on =” [ 1.2 , 1.3 ) ” |
Paket, açıkça dışa aktarılan ve içe aktarılan paketi bildirir ve bunu kontrol etmek için org.eclipse.equinox.http.servlet paketi tarafından kullanılan paketleri arayalım ve yalnızca içe aktarılan paketi kullanıp kullanmadığını doğrulayalım.
1 2 |
from n in Packages where n . IsUsedBy ( “ org . eclipse . equinox . http . servlet_1 . 1.200.v20110502 “ ) select new { n , n . NbBCInstructions } |
Gördüğümüz gibi, kullanılan tüm paketler manifest dosyasında, paket içe aktarma bölümünde belirtilmiştir.
Ancak dışa aktarılan paket, diğer paketlerden kullanılabilecek paketi temsil eder. ExportedPackage arabirimi tarafından temsil edilir ve bu arabirimi kullanarak kapsayıcı sınıflarını arayabiliriz.
1 2 |
from t in Types where t . IsUsing ( “ org . osgi . service . packageadmin . ExportedPackage “ ) select new { t , t . NbBCInstructions } |
Bu yeni yetenekle ilgili ilginç olan şey, paketin iyi tanımlanmış bir sınırı olacak ve ne kullanacağı ve neleri hizmet olarak sunacağı çok iyi belirtilmiş olmasıdır.
Diğer araçları kullanarak içe aktarılan paketleri kullanma kontrolünü zorlayabiliriz, örneğin CQLinq ile bir proje belirtilenler dışındaki paketleri her kullandığında uyarı veren bazı kurallar yazabiliriz, ancak bu kontrolün yürütme ortamında olması daha iyidir, bu nedenle geliştirici bu kuralları çiğneyemezsiniz.
İçe aktarılan ve ihraç edilen paketleri işleme yeteneği, OSGi modülleri katmanı tarafından yönetilir ve bu bizim yapbozun dördüncü parçasıydı.
OSGi konteynerine geri dönelim ve hangi hizmetleri sağladığını keşfedelim?
Konteyner hizmetleri
Konteyner EquinoxLauncher sınıfı tarafından başlatılmadan önce keşfettiğimiz gibi, çerçeve sınıfı paketleri başlatır ve başlatır, hangi hizmetlerin sağlandığını tespit etmek için çerçeve başlatma yönteminde kullanılan tüm sınıfları arayalım.
1 2 |
from t in Types where t . IsUsedBy ( “ org . eclipse . osgi . framework . internal . core . Framework . initialize ( FrameworkAdaptor ) “ ) select new { t , t . NbBCInstructions } |
BundleRepository, BundleHost, PackageAdminImpl ve ServiceRegistry gibi bazı sınıflar daha önce keşfedilmiştir.
Diğer sınıflar ne olacak:
- StartLevelManager:
Her OSGi Paketi, sunucunun paketlerin göreli başlatma ve durdurma sırasını kontrol etmesini sağlayan bir başlangıç seviyesi ile ilişkilendirilir. Yalnızca başlangıç düzeyi sunucu çerçevesinin etkin başlangıç düzeyine eşit veya daha düşük olan paketler etkin olmalıdır. Genellikle, daha küçük bir başlangıç düzeyine sahip bir paket daha erken başlatılır. - GüvenlikYöneticisi:
Güvenlik katmanı, paket işlevselliğini önceden tanımlanmış yeteneklerle sınırlayarak güvenlik yönlerini ele alır. - Organizasyon müdürü:
Olay Yöneticisi hizmeti, olayları işlemek için bir yayınla-abone ol modeli sağlar. OSGi Event Admin Service Spesifikasyonuna göre gerçekleştirilir. Event Admin hizmeti, olay kanalı araya girerek Olay Yayıncıları ve Olay Aboneleri (Olay İşleyicileri) arasında olayları gönderir. Yayıncılar, olayları kanala gönderir ve olay kanalı, hangi işleyicilerin bildirilmesi gerektiğini tanımlar. Böylece yayıncılar ve işleyiciler birbirleri hakkında doğrudan bilgiye sahip değildir ve bu da olay yönetimini basitleştirir.
OSGi'nin bütün resmi
Daha önce anlatılan tüm yapboz parçalarını bir araya getirelim ve aşağıdaki OSGi resmine sahip olacağız:
Bu mimari aşağıdaki ilginç avantajlara sahiptir:
- Basit.
- Azaltılmış Karmaşıklık.
- Kolay Dağıtım.
- Güvenli.
Onu çok çekici yapan ve Detour'a değer kılan şey nedir ve derinlemesine incelerseniz zamanınızı boşa harcamazsınız.