Web应用程序的简单插件系统
我們需要制作多個具有很多共享功能的基于Web的項目。 為此,某種插件系統(tǒng)將是一個不錯的選擇(作為復(fù)制粘貼內(nèi)容的替代方法)。 有些框架(例如grails)可以選擇制作Web插件,但大多數(shù)沒有,因此需要實現(xiàn)定制的東西。
首先,讓我們定義所需的功能。 “插件”:
- 應(yīng)該通過通過maven / ivy導(dǎo)入簡單地包括在內(nèi)
- 如果使用了一個類,應(yīng)該在依賴項注入容器中注冊所有類(自動或通過單行配置)
- 應(yīng)該是垂直的–即包含所有文件,從javascript,css和模板到控制器,再到服務(wù)層類
- 不需要需要在項目之間復(fù)制粘貼的復(fù)雜配置
- 應(yīng)該允許容易的開發(fā)和調(diào)試而無需重新部署
將Java類放入jar文件中,然后添加到lib目錄中,因此也添加到了類路徑中,因此這很容易。 但是我們需要將Web資源提取到各個位置,其余的代碼可以在這些位置使用它們。 有三種通用的方法:構(gòu)建時提取,運行時提取和從類路徑加載運行時。
最后一種方法將需要一個控制器(或Servlet),該控制器從類路徑(相應(yīng)的jar)中加載資源,對其進行緩存并提供服務(wù)。 這有兩個明顯的缺點,其中之一就是放在罐子里,在開發(fā)過程中不容易更換它們。 使用類路徑資源也很棘手,因為您事先不知道文件名。
其他兩種方法非常相似。 例如,Grails使用構(gòu)建時提取–插件是一個zip文件,其中包含所有必需的資源,并且在構(gòu)建項目時將它們提取到各自的位置。 很好,但是需要更多配置(在我們的例子中為Maven),這可能還必須在項目之間復(fù)制。
因此,我們選擇了運行時提取方法。 它在啟動時發(fā)生–加載應(yīng)用程序時,某種啟動偵聽器(在我們的示例中為帶有@PostConstruct的spring組件)會遍歷lib文件夾中的所有jar文件,并從特定文件夾(例如,“ web” ”)。 因此,jar文件的結(jié)構(gòu)如下所示:
comcompanypkgFoo.classBar.class webplugin-namecssmain.cssjsfoo.jsbar.jsimageslogo.pngviewsfoo.jspbar.jsp最終結(jié)果是啟動應(yīng)用程序后,您可以從應(yīng)用程序訪問所有需要的Web資源,因此可以將它們包含在主應(yīng)用程序的頁面(視圖)中。
而且提取的代碼非常簡單(將zip4j用于zip部分)。 這可以是Servlet上下文偵聽器,而不是Spring Bean –沒什么區(qū)別。
/*** Component that locates modules (in the form of jar files) and extracts their web elements, if any, on startup** @author Bozhidar*/ @Component public class ModuleExtractor {private static final Logger logger = LoggerFactory.getLogger(ModuleExtractor.class);@Injectprivate ServletContext ctx;@SuppressWarnings("unchecked")@PostConstructpublic void init() {File lib = new File(ctx.getRealPath("/WEB-INF/lib"));File[] jars = lib.listFiles();String targetPath = ctx.getRealPath("/");String viewPath = "/WEB-INF/views"; //that can be made configurablefor (File jar : jars) {try {ZipFile file = new ZipFile(jar);for (FileHeader header : (List<FileHeader>) file.getFileHeaders()) {if (header.getFileName().startsWith("web/") && !fileExists(header)) {// extract views in WEB-INF (inaccessible to the outside world)// all other files are extracted in the root of the applicationif (header.getFileName().contains("/views/")) {file.extractFile(header, targetPath + viewPath);} else {file.extractFile(header, targetPath);}}}} catch (ZipException ex) {logger.warn("Error opening jar file and looking for a web-module in: " + jar, ex);}}}private boolean fileExists(FileHeader header) {return new File(ctx.getRealPath(header.getFileName())).exists();} }因此,為了制作插件,您只需制作一個帶有jar包裝的Maven項目,并將其作為依賴項添加到您的主項目中,其他所有工作都將得到處理。 如果未啟用對bean的類路徑掃描(或選擇使其成為偵聽器),則可能需要注冊ModuleExtractor 。
注意:此解決方案并非旨在成為能夠解決所有問題的功能齊全的插件系統(tǒng)。 它不支持版本控制,子模塊等。這就是標(biāo)題為何“簡單”的原因。 但是您可以用它做很多事情,而且它的復(fù)雜性非常低。
翻譯自: https://www.javacodegeeks.com/2013/08/a-simple-plugin-system-for-web-applications.html
總結(jié)
以上是生活随笔為你收集整理的Web应用程序的简单插件系统的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 局域网DDOS(局域网可以ddos吗)
- 下一篇: 安卓事件分发流程(安卓事件分发)