RingoJS 与 Java环境集成

RingoJS本身就是构建于Mozilla Rhino之上,Mozilla Rhino是啥——一个Java实现的JavaScript引擎、执行环境…… 这句话对于外人来说,一定觉得很绕……   Java Integration   Ringo的底层JavaScript Engine——Rhino,可以访问任何装载到JVM环境中的Java Class。这就给了Ringo开发者几乎全部的Java功能,Ringo开发者可以在程序中使用Java的丰富库函数。在Ringo中,我们可以访问Java Class的静态(static)方法,访问常量、创建新的Java对象等等。 常用如下三种方式,将Java类文件或者库(library,jar文件)集成进Ringo: 将相关的Java Class或者library放入运行环境的classpath(Ringo本质是一个Java环境) 将Java library(jar文件)放入Ringo的lib文件夹 将Java library(jar文件)或者java package(文件夹)添加到classpath中(配置classpath) 方法1和2都可以seamlessly集成Java对象,Ringo程序中不需显示指定什么java class或者library被集成…… 当然,Java的library和packages也可以在Ringo程序运行过程中显式添加到classpath中,完成集成,Ringo中使用addToClasspath(pathName)来实现这个功能。addToClasspath只有一个参数:pathName,对应要加入的library或者package的绝对路劲。如果想象引入module一样添加java对象,可以使用module.resolve(pathName)方法: addToClasspath(module.resolve(“./library.jar”)) 添加package: addToClasspath(module.resolve(“./package”));   Best Practice: 通常来说,在Ringo模块中,使用addToClasspath()手工加入需要的library或者package是更优选择,原因如下: 最终用户或者程序员,在下载了你的Ringo package后,不需要修改、配置他们的classpath。 不需要手工copy  library到他们的Ringo lib 文件夹 通过addToClasspath()显式添加library和package,如果路径不正确,会抛出异常提示 Explicity adding specific libraries & packages to the classpath serves as a form of documentation for programmers Examples:

JSGI and Stick

JSGI and Stick   这篇文档将描述一个构建web应用程序的框架(framework),该架构构建在JSGI规范基础上,由多个middleware构成,这里的middleware跟我之前已经形成“思维定势”的middleware不太一样,以前一说中间件,想到的是weblogic、jboss之类的application server,这里的middleware没有那么庞大,他们指的就是一些以特定逻辑来处理web request的函数块。 名词定义: JSGI,JSGI对web application的定义,认为web application就是一个function,接受request参数,返回一个response对象,这是一个纯粹的、具有简洁美的概念,所谓function,就是封装具体功能,让外界只关注输入参数类型和返回结果。能够从这个高度看待web application,确实是搞高。JSGI中,定义application就是由多个模块化的middleware组成,这些middleware能够从外部配置。 Application,JSGI application,我们之前已经介绍,就是一个JavaScript函数,接受request,返回response对象,一个最简单的JSGI application应该看起来这个样子: function(request) { return { status: 200, headers: {}, body: [“Hello World!”] }; }   在JSGI规范中,还定义了一个Application对象,其本身当然包含前面说的application功能,另外还有一些额外的方法、特性。后文所说的application对象,指的都是这个。   Middleware,我们指的是一个JSGI application,它能够包裹住另一个JSGI application。request对象是否、如何传递给被包裹的JSGI application,完全由这个middleware来决定。 一个最简化的、不做任何操作的middleware,仅仅是将request作为参数传递给其包裹的内部application,并且返回结果,看起来应该是下面这个样子(nested是被middleware包裹的其他application,已经预先定义): function(request) { return nested(request); }   Middleware Factory, 中间件工厂,姑且这么直译,就是一个JavaScript函数,其接受一个JSGI application作为参数,然后返回一个middleware function。这有点绕,代码看起来应该这个样子: function(nested) { return function(request) { return nested(request); };

Ringo和Spring集成

Ringo with Spring 可以设想,集成了Spring之后,RingoJS就不收任何限制了,JavaScript语言的灵活性,加上Java & Spring 的完善功能,感觉上就应该可以做出很帅的东西…… >> 因为觉得在集成使用Ringo和Spring方面有很多值得一说,Jim Cook就Share了部分他们使用的代码,这部分代码可以让我们更加容易的在Ringo中引用ApplicationContext。下文的例子即基于Jim Cook分享的代码。 Ringo 使用org.ringojs.jsgi.JsgiServlet来bootstrapSSJS环境,我们可以扩展这个类,以提供一些Spring helper函数,帮助我们在Ringo中访问Spring。 package org.ringojs.jsgi;   import org.springframework.context.ApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils;   import javax.servlet.ServletConfig; import javax.servlet.ServletContext; import javax.servlet.ServletException;   publicclass ExtJsgiServlet extends JsgiServlet {   private ApplicationContext _springContext;   @Override public void init(ServletConfig config)throws ServletException { super.init(config); final ServletContext context = config.getServletContext(); _springContext = WebApplicationContextUtils

RingoJS的模块管理

模块化管理越来越有意思,刚开始看到RingoJS中有JSGI,我还猜想是否是OSGi的一个实现,后来才知道不是。RingoJS的模块化管理是CommonJS的一个实现,很Young,很Simple。   Modules in Ringo   Ringo实现了CommonJS Modules1.1规范,在Javascript世界中,存在多个可用Module patterns,但是在Ringo的世界里,我们只用这个: 每一个文件就是一个模块,不需要特别的语法申明 任何function或者其他属性,只要你在module(文件)中,attatch到exports对象上,他们就被导出(让外部可见),成为这个模块的导出属性 require(‘foobar’)会返回一个拥有模块所有exposed属性的对象,代表foobar模块   剖析Module   In Ringo,每一个javascript文件都被当做是一个module,Ringo提供导入、导出的实现。 一个简单的例子会让事情变得更明白。下面我们实现一个foobar.js模块(module),我们希望这个模块提供add方法,而不是其内部私有方法adder: // foobar.js varadder = function(a, b) { return a + b; };   exports.add = function(a, b) { return adder(a, b ); };   这样,我们就完成了一个module的实现,我们现在可以在ringo环境中,通过require引入这个模块,然后调用这个模块对外开放的add方法(以下在Ringo命令行中执行, >>是Ringo命令行提示符): >> varfoobar = require(‘foobar’); >>foobar.add(3, 4); 7 而模块(module)中的私有(没有export)的方法,我们不能调用: >> foobar.adder(2, 2);