java mvel_你的Java开发工具包有没有MVEL?
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?相关推荐
- aws搭建java项目_开发人员指南 - AWS SDK for Java 1.x - 适用于 Java 的 AWS 开发工具包...
本文属于机器翻译版本.若本译文内容与英语原文存在差异,则一律以英文原文为准. 开发人员指南 - AWS SDK for Java 1.x 适用于 Java 的 AWS 开发工具包为 Amazon We ...
- 【Java】浅谈Java的GUI开发
GUI是什么? 图形用户界面(Graphical User Interface,简称 GUI,又称图形用户接口)是指采用图形方式显示的计算机操作用户界面. 图形用户界面是一种人与计算机通信的界面显示格 ...
- java游戏演示ppt_java项目开发实战──五子棋游戏.ppt
java项目开发实战──五子棋游戏.ppt 还剩 23页未读, 继续阅读 下载文档到电脑,马上远离加班熬夜! 亲,很抱歉,此页已超出免费预览范围啦! 如果喜欢就下载吧,价低环保! 内容要点: 第 24 ...
- java面试题(java基础)
1.JDK和JRE有什么区别? JRE: Java Runtime Environment (java运行时环境) JDK:Java Development Kit(java开发工具包) 简单的说就 ...
- 【java毕业设计】基于java+Tomcat +Swing的出租车计价器设计与实现(毕业论文+程序源码)——出租车计价器
基于java+Tomcat +Swing的出租车计价器设计与实现(毕业论文+程序源码) 大家好,今天给大家介绍基于java+Tomcat +Swing的出租车计价器设计与实现,文章末尾附有本毕业设计的 ...
- java微信附件下载_WxJava微信开发工具包
下面我们对WxJava微信开发工具包文件阐述相关使用资料和WxJava微信开发工具包文件的更新信息. WxJava微信开发工具包 WxJava微信开发Java开发工具包(SDK),支持包括微信支付.微 ...
- 2017可以兼容那些jdk_2019从头跃——核心基础:何为JDK?Java开发工具包须知总览...
摘要:JDK是构建Java应用程序的关键平台组件. 其核心是Java编译器. 1.导引 Java Development Kit(JDK)是Java编程中使用的三个核心技术包之一,相伴随的另两个是JV ...
- java开发可重用代码包工具包_[Java教程]彻底搞懂Java开发工具包(JDK)安装及环境变量配置...
[Java教程]彻底搞懂Java开发工具包(JDK)安装及环境变量配置 0 2021-01-04 04:00:04 安装并配置JDK环境变量,不但要知道怎样做,也要知道为什么这样做,知其然知其所以然. ...
- 此安装程序必须使用 java 开发工具包 (jdk) 执行_彻底搞懂Java开发工具包(JDK)安装及环境变量配置...
[官方正版]java jdk 9学习笔记 78.4元 包邮 (需用券) 去购买 > 一.Java 和 JDK 是什么 Java:Java是一种优秀的程序设计语言,它有非常多的语言特性,如简单性. ...
最新文章
- Sublime-text
- Leetcode--3Sum
- 委外订单_ERP软件教程:金蝶ERP的委外加工业务流程(一)
- 服务器性能优化的8种常用方法
- npm ERR! code E404 npm ERR! 404 Not Found - GET https://registry.npmjs.com/@mlamp%2fuser-info-dropdo
- 一体打印机行业调研报告 - 市场现状分析与发展前景预测(2021-2027年)
- DC.SetMapMode()的用法记录
- Python 字典实现原理
- 5个常用的MySQL数据库管理工具
- 考研必备数学公式大全(数学二)(高等数学篇)
- 如何将已有图片做成透明水印_手把手教你如何使用Photoshop CC 2014给图片添加透明水印的教程-网络教程与技术
-亦是美网络...
- 华为手机备份的通讯录是什么文件_华为通讯录怎么导入新手机(三种方法帮你导通讯录)...
- 熟识 : 计算机文化(收藏)
- vue 在线答题功能
- iOSButton文字和图片摆放的个字方式
- lhgdialog弹出框组件 参数详解(自己曾经开发的fuzz项目中用到过)
- web前端设计师需要常去的15个设计博客资源站
- 24. 两两交换链表中的节点
- CentOS7 通过 cups 与 Windows 共享 HP 1020 打印机
- 密码学的安全性浅析-4