MVEL是什么

MVEL最初是Mike Brock的Valhalla项目的表达计算器。Valhalla本身是一个早期的Seam,就像为自动化“out of the box”web应用而生的框架,虽然Valhalla现在是休眠状态,但是MVEL仍旧作为活跃的开发项目向前发展。通常,我们会将MVEL同OGNL、JEXL、JUEL这样的项目作对比;不论是性能、特性还是易用性,尤其是集成方面,MVEL都已经远远超过那些项目。MVEL还没有尝试另一种JVM语言,但是开始关注解决嵌入式脚本的问题。

由于内存限制或者沙盒不能用字节码生成的约束环境中,MVEL则十分理想。取代尝试再创在Java,相反,MVEL目的在于为Java程序员提供一种类似的语法,同时也为短的和简明表达式添加了语法糖衣。

MVEL是Drools规则引擎的一部分,很多密封集成点式同Drools团队一同开发的。那会其他脚本语言可以再次进行复查,但是也显示了一下的问题:缺少可选类型安全

集成不良,通常通过映射填入内容。没有字节码不能运作用字节码生成编译时间慢,还增加了可扩展性问题;不用字节码生成运行时执行非常慢

内存消耗过大

Jar巨大/依赖规模

属性访问函数和数据结构

MVEL支持类javascript语法,这是我们熟悉并喜欢的表达语言,支持简化的属性访问函数,内联映射以及列表:

以下是引用片段:

[1, 2, 3, 4] // array

["key1" : 1, "key2" : 3 ] // map

person.name // simple property accessor

person.pets["rover"].age // map accessor

person.pets["rover"].?age // null safe accessor

使用“with”声明,并内联函数构造器,下面是等价功能:以下是引用片段:

with ( new Person() ) {

name = "Bobba Fet", age = "50"

}

new Person().{

name = "Bobba Fet", age = "50"

}

也可以对复杂数据结构创建使用内联映射和列表语法:以下是引用片段:

[ people : [

new Person().{ name = "Bobba Fet" },

new Person().{ name = "Darth Vader" }

],

places : [

new Place().{ name = "Death Star" }

]

]

在MVEL中就像其他语言一样返回值,默认的是最后一个值。此外,你也可以使用“return”关键词从程序中手动返回。以下是引用片段:

if (val) { “foo”}

else

{ “bar”};

Is the same as:

if (val) { return “foo” }

else

{ return “bar” };

这个例子中通过关键词“room”和“doors”返回一个Map,Door参照了两个room Map中以前创建的实例

以下是引用片段:

rooms = [

"basement" : new Room("basement"),

"lounge" : new Room("kitchen")

];

// return is implicit,

// but can be explicitly added if preferred

doors = [

new Door(

rooms["kitchen"], rooms["basement"]

)

];

[ "rooms" : room, "doors" : doors ];

外部变量词典

MVEL可以使用Map计算给定的表达,提供一个可用变量词典:

以下是引用片段:

Map vars = new HashMap();

vars.put( "person", p );

// p is a previous created instance

//p.pets references a Map.

Dog dog =

( Dog ) MVEL.eval( "person.pets['rover']", vars );

上面所说的将会使用MVEL的“interpreted”模式,快速单程编译和执行String。它也能为更快的执行进行预编译。

MVEL通过性能优化的分析器开发,保持了jar大小,而且意味着MVEL不要求任何附加的外部依赖。Jar大概700kb左右,包括调试信息。编译声明仍旧会被解读,使用一种优化的内部执行图表。对于性能敏感的代码,MVEL的优化程序可以发出字节码来加速域和方法的访问。

编译例子:

以下是引用片段:

ExecutableStatement stmt =

MVEL.compileExpression( "person.pets['rover']" );

MVEL.executeExpression( stmt, vars );

内容对象可用来执行脚本,而不是提供对象。注意下面的例子中,我们可以直接访问“pet的属性”,这对于Person的方法也同样有效:

以下是引用片段:

Dog dog =

( Dog ) MVEL.eval( "pets['rover']", p );

内容对象和变量词典可以共同使用:

以下是引用片段:

vars.put( "otherPet", patch )

// patch is another pet

MVEL.eval(

"pets['rover'].age == otherPet.age", p, vars

);

输入声明可行,“*”也可以成套引进使用:

以下是引用片段:

"import org.domain.Dog; pets['rover'] == new Dog('patch', 7)"

类输入可以通过可重用的ParserConfiguration自动添加,如果这个输入可以被编译中的大多数表达所共享,ParserConfiguration相当不错。以下是引用片段:

ParserConfiguration pconf =

new ParserConfiguration();

pconf.addImport( "Dog", Dog.class );

ParserContext pctx = new ParserContext( pconf );

MVEL.compileExpression(

"pets['rover'] == new Dog('patch', 7)", pctx

);

输入信息和输入安全

ParserContext在外部变量编译时间可随意用于提供输入信息。在哪里提供输入信息,编译器就可以更好的假设,结果就是更快地执行性能。局部变量部署支持类型推断,如果他们可以推断出类型就可以优化。以下是引用片段:

ParserContext pctx = new ParserContext( );

pctx.addInput( “p”, Person.class );

MVEL.compileExpression( "p.pets['rover']", pctx );

此外,MVEL已经能够以非类型安全的方式动态执行,这一点类似其他的表达语言,像OGNL或者JEXL。但是编译要确保所有输入安全,使用可选的强键入。如果输入信息不可用或者不能推断,编译就会失败。

以下是引用片段:

ParserContext pctx = ParserContext.create()

.stronglyTyped()

.withInput(“p”, Person.class);

MVEL.compileExpression( "p.pets['rover']", pctx );

Setting the type of the context object can be done via the 'this' input:

ParserContext pctx = ParserContext.create()

.stronglyTyped()

.withInput( “this”, Person.class );

MVEL.compileExpression( "this.toString()", pctx );

完全的输入推断是为局部变量提供的,所以输入声明或者类型转换的支持是可选的。MVEL也可以从可用的泛型中推断输入信息:以下是引用片段:

public static class Person {

private Map pets;

...

}

...

ParserContext pctx = ParserContext.create()

.stronglyTyped();

.withInput( “person”, Person.class );

//Both the following MVEL statements are valid and type safe:

MVEL.compileExpression( "Pet rover = (Pet) person[“rover”];n”+

“return rover.age;", pctx );

MVEL.compileExpression( "rover = person[“rover”];n”+

“return rover.age;", pctx );

MVEL比较有意思的一项性能是提供分析表达式的功能,而且可以告诉你外部输入,也就是变量不是本地分配的。也可以用于为局部变量报告推断输入。确定了外部输入时,强键入就不能使用,而且输入的内容将会被作为java.lang.Object处理。以下是引用片段:

ParserContext pctx = ParserContext.create();

MVEL.compileExpression( "person.pets['rover']", pctx );

// Map returns [“person” : Object.class]

Map inputs = pctx.getInputs();

从局部变量获取输入:

以下是引用片段:

ParserContext pctx = ParserContext.create()

.stronglyTyped()

.withInput( “person”, Person.class );

MVEL.compileExpression( "pet = person.pets['rover']", pctx );

// Map returns [“pet” : Pet.class]

Map inputs = pctx.getVariables();

索引变量词典

对外部变量词典使用Map是嵌入式脚本语言最常用的方式,但是并不是性能的最优化方式。这回消耗过多的内存,而且每一次读或者写就是一个Map put/get。MVEL的最新版本通过配置属性“indexAllocation”,引入了预计算索引变量,所以读和写变量和访问矩阵一样快速,在内存消耗上不会比矩阵匹配的变量长度需求多。索引也可以用于局部变量,确保高性能。以下是引用片段:

ParserContext pctx = new ParserContext( )

.stronglyTyped()

.withInput(“person”, Person.class)

.withInput(“otherPet”, Person.class)

String[] varNames = new String[] { “person”, “otherPet” };

pctx.addIndexedInput(varNames);

pctx.setIndexAllocation(true);

String exp = “person.pets['rover'].age == otherPet.age”;

SharedVariableSpaceModel model =

VariableSpaceCompiler.compileShared(expr, ctx);

ExecutableStatement stmt = MVEL.compileExpression( expr, pctx );

// Notice the values order must

// match the indexedInput variable name order

Object[] values = new Object[] { person, patch };

MVEL.executeExpression(stmt, model.createFactory(values) );

增强功能可选字节码生成

高度优化实时编译器

编写优化

逃逸分析和冗余优化

总结

到现在你应该可以确信,作为Java开发者你不能把MVEL拿出你的工具盒了吧,MVEL填补了完成编程环境之间独特的代沟,像Groovy和Scala和表达语言OGNL和JUEL。就算全世界在讨论Gavin King的Ceylon项目的各种优点,他们错过了Jboss的秘密武器。

java mvel_你的Java开发工具包有没有MVEL?相关推荐

  1. aws搭建java项目_开发人员指南 - AWS SDK for Java 1.x - 适用于 Java 的 AWS 开发工具包...

    本文属于机器翻译版本.若本译文内容与英语原文存在差异,则一律以英文原文为准. 开发人员指南 - AWS SDK for Java 1.x 适用于 Java 的 AWS 开发工具包为 Amazon We ...

  2. 【Java】浅谈Java的GUI开发

    GUI是什么? 图形用户界面(Graphical User Interface,简称 GUI,又称图形用户接口)是指采用图形方式显示的计算机操作用户界面. 图形用户界面是一种人与计算机通信的界面显示格 ...

  3. java游戏演示ppt_java项目开发实战──五子棋游戏.ppt

    java项目开发实战──五子棋游戏.ppt 还剩 23页未读, 继续阅读 下载文档到电脑,马上远离加班熬夜! 亲,很抱歉,此页已超出免费预览范围啦! 如果喜欢就下载吧,价低环保! 内容要点: 第 24 ...

  4. java面试题(java基础)

    1.JDK和JRE有什么区别? JRE: Java Runtime Environment  (java运行时环境) JDK:Java Development Kit(java开发工具包) 简单的说就 ...

  5. 【java毕业设计】基于java+Tomcat +Swing的出租车计价器设计与实现(毕业论文+程序源码)——出租车计价器

    基于java+Tomcat +Swing的出租车计价器设计与实现(毕业论文+程序源码) 大家好,今天给大家介绍基于java+Tomcat +Swing的出租车计价器设计与实现,文章末尾附有本毕业设计的 ...

  6. java微信附件下载_WxJava微信开发工具包

    下面我们对WxJava微信开发工具包文件阐述相关使用资料和WxJava微信开发工具包文件的更新信息. WxJava微信开发工具包 WxJava微信开发Java开发工具包(SDK),支持包括微信支付.微 ...

  7. 2017可以兼容那些jdk_2019从头跃——核心基础:何为JDK?Java开发工具包须知总览...

    摘要:JDK是构建Java应用程序的关键平台组件. 其核心是Java编译器. 1.导引 Java Development Kit(JDK)是Java编程中使用的三个核心技术包之一,相伴随的另两个是JV ...

  8. java开发可重用代码包工具包_[Java教程]彻底搞懂Java开发工具包(JDK)安装及环境变量配置...

    [Java教程]彻底搞懂Java开发工具包(JDK)安装及环境变量配置 0 2021-01-04 04:00:04 安装并配置JDK环境变量,不但要知道怎样做,也要知道为什么这样做,知其然知其所以然. ...

  9. 此安装程序必须使用 java 开发工具包 (jdk) 执行_彻底搞懂Java开发工具包(JDK)安装及环境变量配置...

    [官方正版]java jdk 9学习笔记 78.4元 包邮 (需用券) 去购买 > 一.Java 和 JDK 是什么 Java:Java是一种优秀的程序设计语言,它有非常多的语言特性,如简单性. ...

最新文章

  1. Sublime-text
  2. Leetcode--3Sum
  3. 委外订单_ERP软件教程:金蝶ERP的委外加工业务流程(一)
  4. 服务器性能优化的8种常用方法
  5. npm ERR! code E404 npm ERR! 404 Not Found - GET https://registry.npmjs.com/@mlamp%2fuser-info-dropdo
  6. 一体打印机行业调研报告 - 市场现状分析与发展前景预测(2021-2027年)
  7. DC.SetMapMode()的用法记录
  8. Python 字典实现原理
  9. 5个常用的MySQL数据库管理工具
  10. 考研必备数学公式大全(数学二)(高等数学篇)
  11. 如何将已有图片做成透明水印_手把手教你如何使用Photoshop CC 2014给图片添加透明水印的教程-网络教程与技术 -亦是美网络...
  12. 华为手机备份的通讯录是什么文件_华为通讯录怎么导入新手机(三种方法帮你导通讯录)...
  13. 熟识 : 计算机文化(收藏)
  14. vue 在线答题功能
  15. iOSButton文字和图片摆放的个字方式
  16. lhgdialog弹出框组件 参数详解(自己曾经开发的fuzz项目中用到过)
  17. web前端设计师需要常去的15个设计博客资源站
  18. 24. 两两交换链表中的节点
  19. CentOS7 通过 cups 与 Windows 共享 HP 1020 打印机
  20. 密码学的安全性浅析-4

热门文章

  1. 计算机存储与I/O系统基础原理笔记
  2. HTML简介(网页的基本组成,什么是HTML,Web标准的三大组成部分),HTML标签(HTML语法规范,标签关系),HTML结构标签(第一个HTML)
  3. HLSL 学习笔记3 法线映射
  4. LINUX内核狂想曲之SLOB分配器
  5. 全国招标公告公示搜索引擎DES des加密,des加密逆向,解密
  6. 26天备考,安全通过雅思经验帖
  7. gcc常用编译选项及相关知识
  8. 俯瞰·明统系列·北伐中原
  9. 《程序设计综合设计》课程设计--电话号码查询系统
  10. (附源码)SSM网约车管理系统 毕业设计 051630