Web应用程序的简单插件系统

我们需要制作多个具有很多共享功能的基于Web的项目。 为此,某种插件系统将是一个不错的选择(作为复制粘贴内容的替代方法)。 有些框架(例如grails)可以选择制作Web插件,但大多数没有,因此需要实现定制的东西。

首先,让我们定义所需的功能。 “插件”:

  • 应该通过通过maven / ivy导入简单地包括在内
  • 如果使用了一个类,应该在依赖项注入容器中注册所有类(自动或通过单行配置)
  • 应该是垂直的–即包含所有文件,从javascript,css和模板到控制器,再到服务层类
  • 不需要需要在项目之间复制粘贴的复杂配置
  • 应该允许容易的开发和调试而无需重新部署

将Java类放入jar文件中,然后添加到lib目录中,因此也添加到了类路径中,因此这很容易。 但是我们需要将Web资源提取到各个位置,其余的代码可以在这些位置使用它们。 有三种通用的方法:构建时提取,运行时提取和从类路径加载运行时。

最后一种方法将需要一个控制器(或Servlet),该控制器从类路径(相应的jar)中加载资源,对其进行缓存并提供服务。 这有两个明显的缺点,其中之一就是放在罐子里,在开发过程中不容易更换它们。 使用类路径资源也很棘手,因为您事先不知道文件名。

其他两种方法非常相似。 例如,Grails使用构建时提取–插件是一个zip文件,其中包含所有必需的资源,并且在构建项目时将它们提取到各自的位置。 很好,但是需要更多配置(在我们的例子中为Maven),这可能还必须在项目之间复制。

因此,我们选择了运行时提取方法。 它在启动时发生–加载应用程序时,某种启动侦听器(在我们的示例中为带有@PostConstruct的spring组件)会遍历lib文件夹中的所有jar文件,并从特定文件夹(例如,“ web” ”)。 因此,jar文件的结构如下所示:

com
   company
      pkg
         Foo.class
         Bar.class
web
   plugin-name
       css
           main.css
       js
          foo.js
          bar.js
       images
          logo.png
       views
          foo.jsp
          bar.jsp

最终结果是启动应用程序后,您可以从应用程序访问所有需要的Web资源,因此可以将它们包含在主应用程序的页面(视图)中。

而且提取的代码非常简单(将zip4j用于zip部分)。 这可以是Servlet上下文侦听器,而不是Spring Bean –没什么区别。

/**
 * 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);

	@Inject
	private ServletContext ctx;

	@SuppressWarnings("unchecked")
	@PostConstruct
	public 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 configurable
		for (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 application
						if (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

注意:此解决方案并非旨在成为能够解决所有问题的功能齐全的插件系统。 它不支持版本控制,子模块等。这就是标题为何“简单”的原因。 但是您可以用它做很多事情,而且它的复杂性非常低。


翻译自: https://www.javacodegeeks.com/2013/08/a-simple-plugin-system-for-web-applications.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值