1. 程式人生 > >OpenCore: OSGi上部署Hibernate的四種方式

OpenCore: OSGi上部署Hibernate的四種方式

本文討論四種解決方案:
1.模型物件(Domain Objects)外掛
模型物件(Domain Objects)集中到獨立的外掛(Bundle)內,Hibernate外掛依賴這些模型物件外掛。這是最簡單的,也是比較糟糕的方式,比較小的基於OSGi的專案可以這也作做。
2.改進的模型物件(Domain Objects)外掛
把模型物件外掛當作Hibernate外掛的Fragments
3. Eclipse-BuddyPolicy與Eclipse-RegisterBuddy方式
Equinox(Eclipse提供的OSGi實現)平臺特有的方式,允許外掛(Bundle)宣告自己的夥伴,讓“夥伴外掛”來動態載入本外掛的類,這也是Hiberate與Equinox整合的官方解決方案。這種方式模型物件無需部署在單獨的外掛內,與業務外掛部署在一起即可,Hibernate外掛也無須依賴模型物件。
具體做法如下:
首先,Hibernate外掛(名稱,例如org.opengoss.orm.hibernate)宣告自身可以作為夥伴外掛,自描述檔案(MANIFEST.MF) 加入描述:
Eclipse-BuddyPolicy: registered
然後,模型物件的業務外掛中把Hibernate外掛加入為夥伴,自描述檔案(MANIFEST.MF) 加入描述:
Eclipse-RegisterBuddy:org.opengoss.orm.hibernate
具體說明文件:

http://www.hibernate.org/311.html
http://www.ibm.com/developerworks/cn/opensource/os-ecl-osgi/index.html
注意:這種方式無法保證在Hibernate最新版本中應用成功。大家可以再試試:)

=======================================
夥伴類載入器選項
首先為 Hibernate 建立外掛。然後建立一個外掛,其中包含與 Hibernate 有依賴關係的特定於域的類。將下列行新增到 Hibernate 外掛清單中:Eclipse-BuddyPolicy: registered。
將下列清單屬性新增到包含特定於域的類或資源的外掛清單中: Eclipse-RegisterBuddy: hibernate。
該行允許外掛通過宣告將自己暴露給 Hibernate 外掛,而它預先並不知道這些外掛。現在,Hibernate 外掛可以看到需要的類,雖然它並沒有專門匯入它們。

=======================================

4.Eclipse Extension Point方式
這是我們目前實現的方式,通過標準的Eclipse擴充套件點與擴充套件機制,我們在Hibernate外掛中plugin.xml配置檔案中宣告下述擴充套件點:

在模型物件外掛中宣告擴充套件,例如:



Hibernate外掛的啟動中,用程式碼配置生成SessionFactory,程式碼如下:
public void start(BundleContext context) throws Exception {
Configuration configuration = new Configuration().configure(new File(
"./etc/org.opengoss.database.hibernate/hibernate.cfg.xml"));
Class[] domainClasses = getDomainClasses();
for (Class domainClass : domainClasses) {
configuration.addClass(domainClass);
}
sessionFactory = configuration.buildSessionFactory();
Dictionarynew Hashtable
props.put("scope", "APPLICATION");
props.put("uid", "Hibernate:SessionFactory");
registration = context.registerService(
SessionFactory.class.getName(), sessionFactory, props);
}
private Class[] getDomainClasses() throws Exception {
List domainClasses = new ArrayList();
IExtensionPoint point = registry
.getExtensionPoint(IConstants.DOMAIN_OBJECT_EXTENSION_POINT);
IExtension[] extensions = point.getExtensions();
for (IExtension extension : extensions) {
IConfigurationElement[] elements = extension
.getConfigurationElements();
for (IConfigurationElement configurationElement : elements) {
Bundle bundle = pluginContext.getBundleBySymbolId(extension
.getNamespaceIdentifier());
Class domainClass = bundle.loadClass(configurationElement
.getAttribute("class"));
domainClasses.add(domainClass);
}
}
return domainClasses.toArray(new Class[domainClasses.size()]);
}
注意:Hibernate內部的類載入機制實在無法令人滿意,儘管我們在這種方式中已經載入所有的模型類物件,但Hibernate內部仍然會呼叫Class.forName()去試圖載入。所以,我們不得不在其自描述檔案(MANIFEST.MF) 中加入描述:
DynamicImport-Package: *
結論:我們傾向於第四種方式,由Eclipse的擴充套件點功能來完成這一職責。不贊成第三種在OSGi規範層作改進的方式,OSGi本身的類載入機制設計非常優美,Buddy外掛破壞了這種優美。