Web应用程序的简单插件系统
我們需要制作多個(gè)具有很多共享功能的基于Web的項(xiàng)目。 為此,某種插件系統(tǒng)將是一個(gè)不錯(cuò)的選擇(作為復(fù)制粘貼內(nèi)容的替代方法)。 有些框架(例如grails)可以選擇制作Web插件,但大多數(shù)沒(méi)有,因此需要實(shí)現(xiàn)定制的東西。
首先,讓我們定義所需的功能。 “插件”:
- 應(yīng)該通過(guò)通過(guò)maven / ivy導(dǎo)入簡(jiǎn)單地包括在內(nèi)
- 如果使用了一個(gè)類(lèi),應(yīng)該在依賴(lài)項(xiàng)注入容器中注冊(cè)所有類(lèi)(自動(dòng)或通過(guò)單行配置)
- 應(yīng)該是垂直的–即包含所有文件,從javascript,css和模板到控制器,再到服務(wù)層類(lèi)
- 不需要需要在項(xiàng)目之間復(fù)制粘貼的復(fù)雜配置
- 應(yīng)該允許容易的開(kāi)發(fā)和調(diào)試而無(wú)需重新部署
將Java類(lèi)放入jar文件中,然后添加到lib目錄中,因此也添加到了類(lèi)路徑中,因此這很容易。 但是我們需要將Web資源提取到各個(gè)位置,其余的代碼可以在這些位置使用它們。 有三種通用的方法:構(gòu)建時(shí)提取,運(yùn)行時(shí)提取和從類(lèi)路徑加載運(yùn)行時(shí)。
最后一種方法將需要一個(gè)控制器(或Servlet),該控制器從類(lèi)路徑(相應(yīng)的jar)中加載資源,對(duì)其進(jìn)行緩存并提供服務(wù)。 這有兩個(gè)明顯的缺點(diǎn),其中之一就是放在罐子里,在開(kāi)發(fā)過(guò)程中不容易更換它們。 使用類(lèi)路徑資源也很棘手,因?yàn)槟孪炔恢牢募?
其他兩種方法非常相似。 例如,Grails使用構(gòu)建時(shí)提取–插件是一個(gè)zip文件,其中包含所有必需的資源,并且在構(gòu)建項(xiàng)目時(shí)將它們提取到各自的位置。 很好,但是需要更多配置(在我們的例子中為Maven),這可能還必須在項(xiàng)目之間復(fù)制。
因此,我們選擇了運(yùn)行時(shí)提取方法。 它在啟動(dòng)時(shí)發(fā)生–加載應(yīng)用程序時(shí),某種啟動(dòng)偵聽(tīng)器(在我們的示例中為帶有@PostConstruct的spring組件)會(huì)遍歷lib文件夾中的所有jar文件,并從特定文件夾(例如,“ web” ”)。 因此,jar文件的結(jié)構(gòu)如下所示:
comcompanypkgFoo.classBar.class webplugin-namecssmain.cssjsfoo.jsbar.jsimageslogo.pngviewsfoo.jspbar.jsp最終結(jié)果是啟動(dòng)應(yīng)用程序后,您可以從應(yīng)用程序訪問(wèn)所有需要的Web資源,因此可以將它們包含在主應(yīng)用程序的頁(yè)面(視圖)中。
而且提取的代碼非常簡(jiǎn)單(將zip4j用于zip部分)。 這可以是Servlet上下文偵聽(tīng)器,而不是Spring Bean –沒(méi)什么區(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();} }因此,為了制作插件,您只需制作一個(gè)帶有jar包裝的Maven項(xiàng)目,并將其作為依賴(lài)項(xiàng)添加到您的主項(xiàng)目中,其他所有工作都將得到處理。 如果未啟用對(duì)bean的類(lèi)路徑掃描(或選擇使其成為偵聽(tīng)器),則可能需要注冊(cè)ModuleExtractor 。
注意:此解決方案并非旨在成為能夠解決所有問(wèn)題的功能齊全的插件系統(tǒng)。 它不支持版本控制,子模塊等。這就是標(biāo)題為何“簡(jiǎn)單”的原因。 但是您可以用它做很多事情,而且它的復(fù)雜性非常低。
翻譯自: https://www.javacodegeeks.com/2013/08/a-simple-plugin-system-for-web-applications.html
總結(jié)
以上是生活随笔為你收集整理的Web应用程序的简单插件系统的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 局域网DDOS(局域网可以ddos吗)
- 下一篇: 使用Apache Mahout创建在线推