利用JSR-223改进Spring框架的动态语言支持
发布时间:2015-07-11 10:01
摘 要 动态语言支持是Spring框架2.0版本的新功能,而Java平台中的动态语言支持直到JDK6版本才有基本实现。本文首先从Spring的工作原理入手分析其实现动态语言支持的静态结构,引入JSR-223提出的动态语言支持框架并与IoC特性结合起来,利用两者的优势改进Spring有限的动态语言支持能力,通过一个应用实例说明了实现方法和应用前景。
关键词 动态语言; Spring2.0 ;控制反转; JSR-223
1 引言
在Java语言中提供对动态语言的支持,其初衷来自于使用动态语言访问Java平台中的信息,并且可以在Java平台的应用服务器中运行动态语言编写的页面,但纯粹使用Java语言实现的动态语言引擎为Java程序员结合动态语言编程造成了很大不便:不同动态语言引擎具有不同的应用程序编程接口,不同的动态语言资源需要分别管理等等。2006年10月Spring2.0版本的发布更是在版本1的基础上提供了更加丰富的特性和可扩展性支持,本文将从2.0版本的可扩展的XML配置特性和动态语言支持入手分析其实现原理,对后者的实现进行改进,并利用JSR-223以新的方式更加简洁地为在Java环境中使用动态语言提供强大的功能和特性。
2 Spring工作原理与动态语言支持
2.1 IoC容器
Interface21公司推出的Spring开发框架(以下简称Spring)经过开放源代码社区和众多项目的应用和实际检验,历经多个版本的发展,已经成长为使用开源技术开发J2EE应用的事实标准。Spring运用“控制反转(以下缩写为IoC)”和“面向方面编程”(以下缩写为AOP)的理念,在正规的设计模式和一整套最佳实践的支持下,为普通Java对象提供了包括轻量级IoC容器、AOP支持、声明式事务、对象-关系模型映射、J2EE集成工具、Web开发框架集成工具和基本的MVC实现等7个主要方面的特性和服务。IoC的概念最早来自于2004年Martin Fowler提出的一种组件装配模式,其核心观点是将组件的配置与使用分开[1]。Spring的IoC容器提供这样一种功能:为那些组成应用程序的主体和其他需要由容器管理的对象(称为bean)提供实例化、定位、配置支持,并通过容器核心接口y. BeanFactory的多个实现的支持,描述并建立并管理这些对象之间的依赖关系。最常见的方式是通过XML配置元数据来对容器管理的bean进行定义,通过Setter注入和构造器注入两种主要的依赖注入方式实现bean之间的依赖管理,从而实现高层次的松耦合。Spring2.0版本为元数据的XML配置方式提供基于XML Schema的“自定义标签”功能,即通过第三方命名空间将自定义bean的配置引入IoC容器的元数据配置,在应用程序开发中更好的融合Spring的IoC功能。
2.2 动态语言支持
动态类型语言的优点在于方便阅读,不需要写非常多的类型相关的代码,但是不方便调试,命名不规范时往往难于理解;而静态类型语言则具有结构非常规范,便于调试,方便类型安全等优点,缺点是为此需要写包中一整套编程接口的设计目的在于定义动态语言支持框架,为多种动态语言的支持提供统一的访问方式,并且以可插入的方式支持动态语言引擎。包括基金会提供Javascript支持的Rhino引擎,sun公司提供Ruby支持的JRuby引擎等等。
3 动态语言集成框架比较
3.1 Spring2.0
目前Spring2.0提供的动态语言支持框架由一个抽象工厂接口及其实现和多个根据脚本引擎定制的工具类组成,其静态结构如图所示。
图1 Spring2.0的动态语言支持框架类图
核心接口ScriptFactory定义创建动态语言实现bean的getScriptedObject方法,以及构造工厂实例所需的脚本资源和Java接口(Spring要求开发者编写的动态语言必须实现至少一个Java接口),其含义是任何一种可以被IoC容器支持的动态语言必须具有Java的类型特性并且以对象实例为单位被容器管理,才能获得容器提供的特性。目前ScriptFactory接口的实现只有3个,分别提供Bsh,Groovy和Ruby语言的支持。
结合Spring提供的XML元数据配置的可扩展性,从对ScriptBeanDefinitionParser类的代码分析可以看出,IoC容器通过如下步骤注册动态语言实现的bean对象:
①在IoC容器中创建一个ScriptFactoryPostProcessor类型的对象实例作为基础设施获取注入依赖能力;
②获取脚本代码片断;
③为ScriptFactory实例配置基本属性;包括刷新脚本资源的时间间隔、指定构造方法等等;
④解析元数据配置中注入的属性。
通过如上步骤,IoC中采用动态语言支持的bean定义就与其他Java语言构造的bean定义没有本质区别了。Spring的优点在于可以通过注入依赖的方式,使用动态语言编写bean实现,和其他Java对象毫无差别的轻易获取Spring提供的各项特性支持。包括在bean的一个生命周期内修改其实现逻辑、简化实现步骤、减少代码规模等等。
3.2 JSR-223
根据JSR-223的动态语言支持框架定义,包中的静态结构如图2所示。
图2 包的类图
核心接口ScriptEngine为动态语言的访问提供了基本的功能方法定义,包括执行脚本、设置和获取脚本变量、创建与Java语言的绑定、执行脚本方法或者函数等等;ScriptContext定义了指定作用域的脚本变量、暴露ScriptEngine实例进行IO操作所需的Reader/Writer方法。
其中的ScriptEngineManager类使用服务提供机制实现脚本引擎的自动发现,只要环境路径中具有相应脚本引擎的ScriptEngine接口实现类,当前线程的ClassLoader就可以获取ScriptEngineFactory实例,从而根据需要创建ScriptEngine实例来访问脚本资源。
目前Java社区为多达20种以上的动态语言引擎提供JSR-223规范的参考实现。
3.3 基本特性比较
以上两种动态语言支持框架的对比
表1 Spring2.0和JSR-223的对比
Spring2.0
JSR-223
实现
方式
根据不同动态语言引擎编写不同的工厂实现类和工具类
JSR-223定义的标准接口及其实现,JDK6提供直接支持
平台
JDK1.4及以上
JDK5及以上
可扩
展性
添加新的工厂实现和工具类;
定义XML元数据Schema、编写相应的解释器实现
可插入的方式加载脚本引擎,JDK级别的多动态语言兼容性
编程
步骤
1.定义Java接口;
2.配置XML元数据;
3.创建bean对象。
1.创建ScriptEngine对象;
2.执行脚本;
3.调用脚本函数或脚本对象。
特性
支持
Spring框架本身提供的包括IoC在内的各项特性;
声明式编程
面向接口的统一编程方法;
需要Java编程获取由表1可以看出,Spring2.0和JSR-223在多个方面具有互补性:
①将JSR-223的可扩展性应用在Spring2.0中,为Spring增加②利用Spring的声明式编程简化JSR-223的编程步骤;
③利用Spring2.0的IoC容器增强动态语言和Java互动能力。
将两者的特性加以结合,将会显着改善Java语言环境中对动态语言的支持能力。
4 使用JSR-223改进Spring的动态语言集成
在Spring中引入JSR-223提供的动态语言框架的目的是为了通过改进Spring2.0的动态语言支持方式,使程序员更方便地实现多种动态语言的支持,从而获取随着JDK5版本的普遍使用,应用JSR-223编程接口将具有基本的平台支持。根据Java对不同动态语言的支持,需要从Java社区的动态语言支持网站[参考]下载JSR-223对特定动态语言支持的参考实现和脚本引擎,并将相关*.jar文件加入环境路径。如使用JDK6版本则默认具有Javascript引擎支持,使用Javascript作为动态语言的话不需要加载额外的jar文件。
4.2 设计模式
从GoF设计模式的构造型模式来看,Spring采用基本的工厂方法模式和IoC的依赖注入能力实现动态语言的支持;JSR-223的静态结构中采用抽象工厂模式,和Spring不同的是这个抽象工厂本身提供了独立于各种动态语言之外的抽象实现,为特定动态语言的工厂对象提供了部分方法的基本实现。在设计模式的层面上两者没有冲突。
4.3 静态结构
图3 采用JSR-223的Spring动态语言支持框架
两者都采用面向接口编程的原则作为实现基础,通过设计一个AbstractScriptFactory的抽象类,在其内部使用JSR-223的编程接口替换各个特定动态语言的引擎接口,从而将Spring的动态语言支持框架与特定引擎解耦。类图如图3所示。
4.4 抽象类的方法的实现
使用JSR-223提供的编程接口和Java的动态代理技术完成ScriptFactory的抽象实现AbstractScriptFactory,在这个类里按照Spring的ScriptFactory接口方法,使用ScriptEngine类型替换生成动态语言对象的工具类。特定动态语言的支持只需要继承这个抽象类,设置动态语言的引擎名称即可,不需要修改Spring本身的可扩展XML元数据配置机制。其中内部类片断如下。
4.5 特定动态语言的支持
使用该改进方案重新实现JRubyScriptFactory,只在构造方法中调用了setEngineName方法设置了引擎名称:
public JRubyScriptFactory(
String scriptSourceLocator, Class[] scriptInterfaces) {
super(scriptSourceLocator, scriptInterfaces);
ineName("jruby");
}
新的JRubyScriptFactory实现和Spring提供的默认实现相比,编码中除了JRuby的异常类型之外没有对JRuby的显式依赖,代码从需要编写特定的工具类减少到只剩一个构造方法。同时只需在环境路径中加载JSR-223对JRuby的参考实现即可。
按照改进的动态语言支持方案,为Spring2.0添加Javascript支持不需要程序员过多熟悉Rhino引擎的编程接口,只需要根据bean定义的方法调用要求,继承AbstractFactory类并覆盖实现createScriptObject方法,替换Javascript函数的调用方法即可。
4.6 元数据配置
完成以上所需的类文件编写,如果不引入新的动态语言支持,则不需要任何额外的修改;若引入新的动态语言支持,则需要通过修改Spring2.0提供的元数据扩展功能增加动态语言支持的元数据配置命名空间,从而在Spring中以声明的方式实现动态语言集成功能。如增加对Javascript的支持,修改步骤
(1)修改元数据配置的schema文件
xsd:element
name="Javascript"
type="dynamicScriptType"
xsd:annotation xsd:documentation![CDATA[
A Spring bean backed by a piece of Javascript.
]]/xsd:documentation
/xsd:annotation
/xsd:element
(2)在LangNamespaceHandler类的init方法中注册动态语言的解析器:
public void init(){
if(ent(
"criptEngine"))
registerBeanDefinitionParser("Javascript",new ScriptBeanDefinitionParser());
...
}
(3)编译并打包:完成类文件和schema文件的修改后,按照可扩展的XML元数据配置要求完成handler和schema的注册,并且编译生成jar文件即可。
5 结束语
5.1 动态语言的特性和IoC的结合
在Java开发中使用动态语言的特性可以显着降低Java编程的规模。如在数据处理中常用的集合类操作,在使用Java编程时接口类型只定义了25个实例方法,而Ruby语言中的Array类提供了78个方法。程序员在进行一般的功能性操作时往往更关注于直接能够使用的实例方法,不会使用Spring的IoC容器为动态语言提供了良好的对象边界定义和依赖注入功能。除了Ruby和Groovy等动态语言本身就提供了完整的面向对象支持,其他部分动态语言的面向对象支持能力有限,同时这些动态语言本身的编程风格和语法特性往往被局限在领域内部:如Rhino引擎为Javascript提供了名为E4X的XML操作功能,为Javascript增加了语法层次上的增强。而将这种语法增强移植到Java语言中并不是一件轻易的事。而如果根据需求定义动态语言的接口类型,使用IoC容器注入XMLObject类型的对象(如XML格式的数据结果集)、嵌入Javascript函数就可以在接口类型定义的作用域中使用E4X语法操作XML对象(如图4所示)。
图 4 在Spring实现的Javascript集成中应用E4X特性
5.2 实现Spring与动态语言的可插入方式集成
在没有JSR-223提供的动态语言编程框架之前,Spring2.0版本只能提供有限的动态语言支持,而且随着不同动态语言引擎的版本更新,其中每一个ScriptFactory的实现类都必须进行单独的修改以适应新版本的动态语言引擎。JSR-223的脚本语言编程框架为各种动态语言定义了一致的编程接口,有利于解决多种动态语言的向Java平台的移植和语言本身的向后兼容性,同时扩充了Spring对动态语言支持的静态结构,真正实现Spring对动态语言的可插入方式集成。
参考文献
[1] Martin Fowler. Inversion of Control Containers and the Dependency Injection [EB/OL].
, 2004-01-23
Mike Grogan, JSR-223: Scripting for the JavaTM Platform [EB/OL].
,2006-08-10
Rod Johnson,The Spring Framework – Reference Documentation [EB/OL],
,2007,1
GOF, 李英军. 设计模式[M]. 北京:机械工业出版社,2000
热门论文
- 利用JSR-223改进Spring框架的动态语言支持
- 可支持多语言的工作流动态演进
- Spring框架的事务管理应用分析
- 实现基于Spring框架应用的权限控制系统
- 利用Web服务架构对网络安全支付协议的改进
- 保护和促进语言发展的国际法律框架
- 基于Spring框架应用的权限控制系统的研究和实现
- 支持翻转课堂的移动学习APP内容模块框架系统构
- 英语语言文学论文基本框架
- 浅析IT支持体系的基本框架及主要内容
- 基于动态口令的SET改进及移动支付技术发展
- 汉语言文学毕业论文框架
- 大学生网络创业途径与支持体系框架
- 基于Spring MVC框架的电商平台的研究问题和发展
- 对企业战略并购决策的信息结构与支持框架