`
wenshao
  • 浏览: 271300 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

阿里巴巴开源项目SimpleEL发布0.1版本

阅读更多
Simple EL是一个表达式解析引擎。它将表达式解析分成四个部分:预处理、编译、缓存和执行。这四个步骤任意一部分都可以替换,类似设计模式中的Template Method。 SimpleEL将表达式处理成Java Source,调用Tools.jar的Javac API动态编译,缓存编译后反射得到的实例,使得表达式的解析速度和Java静态编译的速度接近。

这是一个性能极致、扩展性良好的表达式解析引擎。图示http://code.alibabatech.com/wiki/download/attachments/1966084/simple_el.png?version=2&modificationDate=1302249958000
目前SimpleEL有三种实现,缺省实现,TinyEL,QL,其中TinyEL在下一个版本中将会替换为缺省实现,QL是一种类SQL的表达式语言,它试图创造一种对象查询语言。

Slider : http://code.alibabatech.com/svn/SimpleEL/trunk/doc/SimpleEL.pptx
SVN:http://code.alibabatech.com/svn/simpleel
JIRA:http://code.alibabatech.com/jira/browse/simpleel
WIKI:http://code.alibabatech.com/wiki/display/simpleel/Home

Download: http://code.alibabatech.com/wiki/display/SimpleEL/Download

Maven Repository:
<repository>
	<id>opensesame</id>
	<name>Alibaba OpenSource Repsoitory</name>
	<url>http://code.alibabatech.com/mvn/releases/</url>
	<snapshots>
		<enabled>false</enabled>
	</snapshots>
</repository>


<dependency>
	<groupId>com.alibaba</groupId>
	<artifactId>SimpleEL</artifactId>
	<version>0.1</version>
</dependency>



import com.alibaba.simpleEL.eval.DefaultExpressEvalService;
import com.alibaba.simpleEL.preprocess.DefaultVariantResolver.Type;

DefaultExpressEvalService service = new DefaultExpressEvalService();
service.regsiterVariant(int.class, "a", "b");

Map<String, Object> ctx = new HashMap<String, Object>();
ctx.put("a", 3);
ctx.put("b", 4);

Assert.assertEquals(7, service.eval(ctx, "@a + @b"));


DefaultExpressEvalService service = new DefaultExpressEvalService();
service.regsiterVariant(int.class, "a", "b");
service.setAllowMultiStatement(true); //support multi-statement

Map<String, Object> ctx = new HashMap<String, Object>();
ctx.put("a", 3);
ctx.put("b", 4);

Assert.assertEquals(1, service.eval(ctx, "if (@a > @b) { return @a - @b; } else {return @b - @a; }"));


TinyEL是SimpleEL中的一种实现,和SimpleEL的缺省实现不同的是,它的预处理不是简单的替换变量,而是经过语法分析之后生成Java Source。变量名称不需要使用@标识。 TinyEL在下一个版本中,可能会升级为SimpleEL的缺省实现。
使用示例:
调用方法
import com.alibaba.simpleEL.dialect.tiny.TinyELEvalService;

TinyELEvalService service = new TinyELEvalService();

service.regsiterVariant(String.class, "name");

Map<String, Object> ctx = new HashMap<String, Object>();
ctx.put("name", "abc");

Assert.assertEquals(5, service.eval(ctx, "('aa' + name).length()"));



* 调用静态方法

TinyELEvalService service = new TinyELEvalService();

service.regsiterVariant(int.class, "a", "b"); //注册a和b两个变量为int类型

Map<String, Object> ctx = new HashMap<String, Object>();
ctx.put("a", 3);
ctx.put("b", 4);

Assert.assertEquals(4, service.eval(ctx, "java.lang.Math.max(a, b)"));



* 构造对象
TinyELEvalService service = new TinyELEvalService();

service.regsiterVariant(long.class, "millis");

long millis = System.currentTimeMillis();
Map<String, Object> ctx = new HashMap<String, Object>();
ctx.put("millis", millis);

Assert.assertEquals(new java.util.Date(millis), service.eval(ctx, "new java.util.Date(millis)"));


* 三元表达式
TinyELEvalService service = new TinyELEvalService();

service.regsiterVariant(int.class, "a", "b");

Map<String, Object> ctx = new HashMap<String, Object>();
ctx.put("a", 3);
ctx.put("b", 4);

Assert.assertEquals(4, service.eval(ctx, "a > b ? a : b"));
Assert.assertEquals(true, service.eval(ctx, "a instanceof Number"));


* 数组访问
TinyELEvalService service = new TinyELEvalService();

service.regsiterVariant(int.class, "a", "b");
service.regsiterVariant(int[].class, "c");

Map<String, Object> ctx = new HashMap<String, Object>();
ctx.put("a", 3);
ctx.put("b", 4);
ctx.put("c", new int[] { 1, 2 });

Assert.assertEquals(4, service.eval(ctx, "Math.max(c[0], c[1]) + 2"));


* 注册函数
TinyELEvalService service = new TinyELEvalService();

service.regsiterVariant(int.class, "a", "b");
service.registerFunction("max", Math.class.getMethod("max", new Class<?>[] { int.class, int.class }));

Map<String, Object> ctx = new HashMap<String, Object>();
ctx.put("a", 3);
ctx.put("b", 4);

Assert.assertEquals(7, service.eval(ctx, "a + b"));
Assert.assertEquals(true, service.eval(ctx, "a < b"));
Assert.assertEquals(4, service.eval(ctx, "max(a, b)"));


* 各种运算符
TinyELEvalService service = new TinyELEvalService();

service.regsiterVariant(int.class, "a", "b");

Map<String, Object> ctx = new HashMap<String, Object>();
ctx.put("a", 3);
ctx.put("b", 4);

Assert.assertEquals(3, service.eval(ctx, "a++"));
Assert.assertEquals(4, ctx.get("a"));
Assert.assertEquals(5, service.eval(ctx, "++a"));
Assert.assertEquals(5, ctx.get("a"));
Assert.assertEquals(4, service.eval(ctx, "--a"));
Assert.assertEquals(4, ctx.get("a"));
Assert.assertEquals(true, service.eval(ctx, "a > b || b > a || a == b"));
Assert.assertEquals(false, service.eval(ctx, "a > b && b > a && a == b"));
Assert.assertEquals(false, service.eval(ctx, "a != b"));


* 使用if语句 
TinyELEvalService service = new TinyELEvalService();
service.setAllowMultiStatement(true);
service.regsiterVariant(int.class, "a", "b");

Map<String, Object> ctx = new HashMap<String, Object>();
ctx.put("a", 3);
ctx.put("b", 4);

Assert.assertEquals(1, service.eval(ctx, "if (a > b) { return a - b; } else {return b - a; }"));


* 声明本地变量
TinyELEvalService service = new TinyELEvalService();
service.setAllowMultiStatement(true);
service.regsiterVariant(int.class, "a", "b");

Map<String, Object> ctx = new HashMap<String, Object>();
ctx.put("a", 3);
ctx.put("b", 4);

Assert.assertEquals(70, service.eval(ctx, "int i = 10; return a * i + b * i;"));


* 使用While
TinyELEvalService service = new TinyELEvalService();
service.setAllowMultiStatement(true);
service.regsiterVariant(int.class, "a", "b");

Map<String, Object> ctx = new HashMap<String, Object>();
ctx.put("a", 3);
ctx.put("b", 4);

Assert.assertEquals(48, service.eval(ctx, "int i = 0; while (i < 10) { a += i++; } return a;"));

Assert.assertEquals(48, ctx.get("a"));
Assert.assertEquals(4, ctx.get("b"));


* 使用For
TinyELEvalService service = new TinyELEvalService();
service.setAllowMultiStatement(true);
service.regsiterVariant(int.class, "a", "b");

Map<String, Object> ctx = new HashMap<String, Object>();
ctx.put("a", 3);
ctx.put("b", 4);

Assert.assertEquals(52, service.eval(ctx, "for (int i = 0; i < 10; ++i) { a += i; } return a + b;"));

Assert.assertEquals(48, ctx.get("a"));
Assert.assertEquals(4, ctx.get("b"));


* 使用ForEach
TinyELEvalService service = new TinyELEvalService();
service.setAllowMultiStatement(true);
service.regsiterVariant(int[].class, "a");

Map<String, Object> ctx = new HashMap<String, Object>();
ctx.put("a", new int[] {1, 2, 3, 4, 5});

Assert.assertEquals(15, service.eval(ctx, "int sum = 0; for (int i : a) { sum += i; } return sum;"));



分享到:
评论
22 楼 lwb314 2016-11-23  
String相加不支持啊
21 楼 lwb314 2016-11-22  
if后边连续接多个else if 好像不支持
20 楼 lwb314 2016-11-03  
之前的文档都已经不能下载了,请问一下。
我如果希望同时执行
如下代码
我发现如果设置service.setAllowMultiStatement(true);  第一行就会报错,不设置第二行就会报错,有什么解决办法吗?
service.eval(ctx, "a > b || b > a || a == b");
service.eval(ctx,"for (int i = 0; i < 10; ++i) { a += i;b++; } return 0;");


第二个问题,是不是所有表达式都需要有个return?比如if或者for,如果我只想赋值比如
if(a>b){a--;}而不需要有什么返回值,这个时候也必须写个return吗?
19 楼 deepthink 2013-08-19  
感觉simpleel貌似没有自己的类型系统,沿用的也都是java的类型系统,所以在实例代码中出现了:
service.regsiterVariant(int.class, "a", "b");  

用来注册类型

但是,我个人对el的理解是必须要有弱的类型系统才能真正的发挥表达式语言的威力,
举个简单例子说:
if(b){
    ....
}

这里的b不管是String类型的'true'或者是boolean类型的true,亦或是object类型的一个非null对象,该条件都应该成立(不清楚simpleel对这种情况是否支持)。
之前曾经在csdn上看过一篇关于simpleel的分析文章,其中提到了simpleel在类型上的硬伤,不过不好意思,文章的地址找不到了。

当然,一种语言的存在可能是可能是为了一个设计目标的实现,对于对性能要求高的系统来说,可以做一个取舍,以牺牲一部分的灵活性来达到高性能的目的,个人理解这是simpleel的真正的用武之地。

不过目测ali的开源项目貌似都是以性能为最终目标的,之前看的httl也是需要注册很多类型信息才能使用
18 楼 carfily 2011-08-04  
这是个好东西,以前都想过要是java有这种功能就好了,现在终于出现了。
17 楼 gazeldx 2011-04-27  
看到这一句
Assert.assertEquals(48, service.eval(ctx, "int i = 0; while (i < 10) { a += i++; } return a;")); 

解决了我一直以来的问题:java代码如何复用,如何像freemarker之类的语言般使用。
16 楼 wenshao 2011-04-25  
vvggsky 写道
wenshao 写道
freish 写道
能不能把那个@去掉呢?


TinyELEvalService的实现是不需要使用@的,看例子!


你们内部 有个大侠 公开 对 这个项目 的实现方式表示过异议!


能够提供更多的信息么?
15 楼 vvggsky 2011-04-25  
wenshao 写道
freish 写道
能不能把那个@去掉呢?


TinyELEvalService的实现是不需要使用@的,看例子!


你们内部 有个大侠 公开 对 这个项目 的实现方式表示过异议!
14 楼 iq527 2011-04-23  
http://code.alibabatech.com/svn/simpleel
13 楼 Allen 2011-04-23  
这些利用EL从各种“数据源”里面获得数据的感觉上很有.NET里面LINQ的思路啊……
12 楼 sky_dream 2011-04-23  
List<Person> srcCollection = new ArrayList<Person>(); 
    srcCollection.add(new Person(18, "吴能")); 
    srcCollection.add(new Person(27, "刘芒")); 
    srcCollection.add(new Person(40, "黄警")); 
    srcCollection.add(new Person(50, "夏留")); 
    srcCollection.add(new Person(60, "刘晶")); 
    srcCollection.add(new Person(33, "石榴姐")); 
    srcCollection.add(new Person(90, "松下太郎")); 

LZ你太强了!
11 楼 ibadboy 2011-04-23  
不知在实际的项目中能起到多大作用,主要的应用场景是什么,期待详细的解释。。。
10 楼 gogole_09 2011-04-23  
利用模版生成java源代码,交给jdk编译执行,nice! 
9 楼 javatar 2011-04-23  
温少,贴一下性能对比吧,EL解析的工具很多,估计大家对性能会比较感兴趣。
8 楼 wenshao 2011-04-22  
freish 写道
能不能把那个@去掉呢?


TinyELEvalService的实现是不需要使用@的,看例子!
7 楼 lwjlaser 2011-04-22  
很好很强大,下下代码来慢慢学
6 楼 freish 2011-04-22  
能不能把那个@去掉呢?
5 楼 wzju64676266 2011-04-22  
温绍锦  ?
4 楼 william_ai 2011-04-22  
有点意思,和以前玩过的一个开源beanshell很像,抽空做个测试玩玩。
3 楼 bill.830420 2011-04-22  
支持开源,功能越来越强大了,现在支不支持在脚本中定义class呢?

相关推荐

    对阿里巴巴开源的babelpluginimport项目的注解

    "对阿里巴巴开源的babel-plugin-import项目的注解" 这个标题表明我们将探讨一个由阿里巴巴贡献的开源项目——`babel-plugin-import`。这个项目是针对JavaScript开发中的一个工具,它主要功能是对`import`语句进行...

    阿里巴巴微服务开源项目盘点.docx

    这些阿里巴巴开源项目不仅在国内,也在全球范围内产生了广泛的影响,推动了微服务架构的发展和落地。它们的广泛应用和持续更新,反映了阿里巴巴对开源社区的贡献,也体现了中国企业在技术创新和标准化方面的领导地位...

    druid.rar阿里巴巴开源数据库连接池

    Druid为监控而生的数据库连接池,它是阿里巴巴开源平台上的一个项目。Druid是Java语言中最好的数据库连接池,Druid能够提供强大的监控和扩展功能.它可以替换DBCP和C3P0连接池。Druid提供了一个高效、功能强大、可...

    阿里巴巴开源大数据平台演进之路 - 王峰(莫问)-阿里云

    阿里巴巴开源大数据平台的发展历程可以分为三个主要阶段:基于Hadoop构建的第一代大数据平台、大数据上云及实时化演进、以及大数据进入云原生时代。 第一阶段:基于Hadoop构建第一代大数据平台(2009-2015) 在这一...

    checkstyle导入阿里巴巴规范流程

    安装完成后,你需要获取阿里巴巴的Checkstyle配置文件,这通常可以在阿里巴巴开源项目的GitHub仓库中找到,如Alibaba Java Coding Guidelines。 1. **配置Checkstyle**: - 在Eclipse中,你可以通过Window -&gt; ...

    阿里巴巴 开发规范插件 离线包

    5. **版本更新**:随着阿里巴巴编码规范的不断演进,插件也会定期更新,以保持与最新规范的一致性,确保开发者始终遵循最佳实践。 6. **社区支持**:阿里巴巴开发规范插件有一个活跃的开发者社区,用户可以在这里...

    阿里巴巴开源的诊断工具Arthas介绍.ppt

    Arthas(阿尔萨斯)是阿里巴巴开源的 Java 诊断工具,开始在淘宝内部孵化使用,后来成为阿里java项目必须使用的内部工具。2018年arthas成为ali开源项目,代码托管在github上。这是带给java系一大福音,项目深受...

    阿里巴巴普惠体(完整版)

    阿里巴巴普惠体是一款由阿里巴巴集团设计并发布的开源字体,旨在为全球用户提供免费、全面的中文字体解决方案。这款字体覆盖了广泛的语言和字符集,包括简体中文、繁体中文、拉丁字母、希腊字母、西里尔字母以及日...

    基于阿里巴巴开源的MNN多语言神经网络设计源码

    该项目是阿里巴巴开源的MNN多语言神经网络设计源码,包含3095个文件,涵盖C++、Python等多种编程语言,涉及源代码、配置文件、文档等多种类型。

    阿里巴巴开源在线分析诊断工具Arthas(阿尔萨斯)

    结合阿里巴巴的其他开源项目,如Sentinel(流量控制)、Hystrix(断路器)、Dubbo(服务治理框架)等,Arthas可以为整个微服务架构提供全方位的诊断能力。 总之,Arthas作为一款强大的在线分析诊断工具,极大地提高...

    阿里巴巴自动登录+私信聊天源码开源+淘宝阿里巴巴营销软件

    该开源项目是一个基于阿里巴巴生态的自动化工具,主要功能包括自动登录和私信聊天。通过分析提供的文件名"已完成-阿里旺旺自动发消息",我们可以推测这个工具专注于阿里旺旺平台的消息发送。以下是对相关知识点的...

    基于阿里巴巴开源的Java诊断工具Arthas设计源码的解析与应用

    本项目深入解析并应用了阿里巴巴开源的Java诊断工具Arthas的设计源码,涉及1228个文件,涵盖653个Java源文件、159个Markdown文档、151个PNG图片、74个Vue文件、28个XML文件、26个JPG图片、22个JavaScript文件、18个...

    阿里巴巴Web及框架简介

    Webx是阿里巴巴开源的一款基于Java的企业级Web应用框架,它旨在提高开发效率,简化项目构建,同时保证系统的稳定性和可扩展性。 Webx框架的核心特性包括: 1. **模块化设计**:Webx采用模块化设计,将系统功能拆分...

    基于阿里巴巴开源的Java诊断工具Arthas的设计源码分析

    该项目深入剖析了阿里巴巴开源的Java诊断工具Arthas的设计源码,包含2000个文件,涵盖894个Markdown文件、596个Java源文件、151个PNG图像文件、129个JSON文件、68个Vue文件、27个XML文件、26个JPG文件、18个...

    阿里巴巴springcloud全家桶项目

    《阿里巴巴SpringCloud全家桶项目详解》 在现代企业级应用开发中,Spring Cloud与Spring的结合已经成为构建微服务架构的主流选择。阿里巴巴作为全球领先的互联网技术公司,也贡献了其在微服务领域的丰富实践,形成...

    阿里巴巴普惠体.zip

    阿里巴巴普惠体是一款由阿里巴巴集团设计并发布的开源字体,旨在为全球用户提供免费、全面且多语言的字体解决方案。这款字体的设计理念是“普惠”,意味着它希望让更多的人和企业能够无负担地使用高质量的字体,促进...

    Qt使用阿里巴巴普惠体示例

    在本文中,我们将深入探讨如何在Qt应用程序中使用阿里巴巴普惠体这一开源字体,以避免因字体版权问题引发的商业纠纷。Qt是一个强大的跨平台应用程序开发框架,它支持多种编程语言,如C++和QML,使得开发者能创建美观...

    藏经阁-【云栖精选12月刊】2017年,阿里巴巴开源那些事.pdf

    藏经阁-【云栖精选12月刊】2017年,阿里巴巴开源那些事.pdf

    阿里巴巴中间件介绍

    通过开源项目,阿里巴巴能够更快地获取最新的技术创新,并与其他开发者共享成果。这种开放的合作模式有助于构建一个更加健康、繁荣的技术生态系统。 综上所述,阿里巴巴在中间件领域的探索和实践不仅为其自身带来了...

    仿阿里巴巴PHP英文版b2b源码

    【标签】中的“仿阿里b2b”表明源码模仿了阿里巴巴B2B网站的部分设计和交互,可能是为了提供类似用户体验或作为学习参考。"php英文b2b"强调了这是基于PHP编程语言的B2B系统,适合英文市场。"php开源b2b"则进一步指出...

Global site tag (gtag.js) - Google Analytics