第一個困難是知道擴展器何時完成了捆綁包的處理。 例如,一旦驅動了任何束激活器,包含藍圖XML文件的束將轉換為ACTIVE狀態。 但這還不是全部。 管理員對何時可以使用捆綁軟件很感興趣,因此處女座中的管理代碼會跟蹤擴展程序的進度,并為代表捆綁軟件的安裝工件提供混合狀態。 安裝工件會一直處于STARTING狀態,直到發布了應用程序上下文為止,此時該應用程序過渡到ACTIVE。 如果沒有這樣的附加基礎架構,管理員將無法確定由擴展程序處理的捆綁包何時真正準備就緒。
那是成功的案例,但在錯誤案例中也有復雜之處。 第一個復雜之處在于,由于擴展程序在與安裝捆綁軟件的線程不同的線程中運行,因此如果擴展程序拋出異常,則不會傳播到安裝捆綁軟件的代碼。 因此,安裝程序需要以某種方式檢查錯誤。 因此,處女座擁有檢測此類錯誤并將其傳播回啟動捆綁軟件部署的線程的基礎架構:部署操作失敗,并顯示堆棧跟蹤,指出出了什么問題。
另一個錯誤并發癥是處理擴展器的擴展器存在(可能不確定)延遲。 對于這種錯誤,Virgo會跟蹤擴展程序處理的進度,并向事件日志發出警告(旨在引起管理員的注意),指出哪些處理過程已延遲以及在某些常見情況下(例如,當藍圖正在等待依賴項時) ,是什么導致延遲。
擴展程序需要能夠查看包的生命周期事件,因此對于將框架進行分區的系統,必須將每個擴展程序安裝到多個分區中。 在另一方面,防止擴展程序的多個實例看到相同的捆綁包事件至關重要,否則它們都將嘗試擴展捆綁包。
擴展器的另一個問題是需要使它們保持運行和健康,因為除了擴展器未處理的捆綁包外,幾乎沒有跡象表明擴展器已關閉或生病。 處女座小心確保其擴展器正確啟動,并且其用于檢測延遲的基礎結構有助于診斷擴展器崩潰或疾病(這兩種情況均極為罕見)。
將參數傳遞給擴展程序以影響其行為也存在問題。 通常,這是通過將擴展程序配置嵌入正在處理的包中或將包含配置的片段附加到擴展程序包中來完成的。 但是,由于擴展器不是由API驅動的,因此無法在調用時傳遞參數的常規方法。 本質上,擴展程序模型意味著用于部署的編程模型僅限于BundleContext.installBundle。
通過在其他基礎架構上進行大量投資,處女座設法合理地支持了Blueprint和Spring DM擴展器。 但是對于Web應用程序擴展器,Virgo無法使其足夠強大,因此它直接從Virgo部署管道中驅動了基礎Web組件,從而避免了上述問題。
我知道至少有另一個服務器運行時項目在擴展器上遇到了類似的問題,因此處女座并不孤單。 在將安裝程序與特定于資源的處理松散耦合,擴展程序模式的主要優勢(但遠非該模式唯一)與提供健壯的編程模型和可用的管理視圖之間進行權衡取舍。服務器運行時-如果沒有擴展程序,這將更加直接。
參考: 擴展程序:模式還是反模式? 從我們的JCG合作伙伴 Glyn Normington在Mind the Gap博客中獲得。
翻譯自: https://www.javacodegeeks.com/2012/08/extenders-pattern-or-anti-pattern.html