jsr223 java_JSR223 Java使用脚本引擎动态修改业务逻辑

本文来自图灵社区 @fairjm 转截请注明出处

偶尔会有一些业务需求是需要在动态改变线上代码的行为.一般的做法是使用个配置文件,存在数据库或者redis等存储中,程序动态获取之后解析并根据配置进行相应的操作.

在配置不复杂的情况下这样的做法能够满足需求.但如果配置很复杂,或者配置的规则很多,那么解析配置并运行就变成了一件很麻烦的事情.可能会引入一些解析器,或者Criteria这样的类.

如果这样,那是不是嵌入一段代码动态加载运行会不会简单点?

好在java本身就提供了这样的机制,也就是JSR-223.

因为是开发使用的,所以最好还是用和java一样的语法,方便现有开发,那选取的脚本语言为groovy比较合适,毕竟能兼容java语法.

搞起.

首先引入依赖:

org.codehaus.groovy

groovy-jsr223

2.4.7

这边用判断用户是否能够访问作为例子.

其中要考虑的用户类如下(省略getter setter和构造器):

public class User {

private String userName;

private Long userId;

private Boolean isVip;

private Integer gender;

private Integer age;

现在的规则是如果是非生产环境返回true,会员返回true,用户以test开头(这只是例子 千万别学)返回true 如果性别是男性并且大于18岁返回true(咦)

对应的groovy脚本如下:

if (!prod) {

return true;

}

if (Boolean.TRUE.equals(user.getIsVip())) {

return true;

}

if (user.getUserName()?.startsWith("test")) {

return true;

}

if (user.getGender()?.equals(1) && user.getAge() != null && user.getAge() >= 18) {

return true;

}

return false;

?表达式可以减少空判断,因为groovy兼容java,所以手工写 != null(比如age)也是可以的.

接来下执行:

// 获取脚本引擎

final ScriptEngineManager factory = new ScriptEngineManager();

final ScriptEngine engine = factory.getEngineByName("groovy");

// 读取脚本

String str;

try (BufferedReader reader = new BufferedReader(

new InputStreamReader(

GroovyScriptTest.class.getResourceAsStream("/groovy-script")))) {

str = reader.lines().collect(Collectors.joining("\r\n"));

}

final User u = new User("fairjm", 1L, false, 1, 18);

// groovy的引擎是支持可编译的所以直接这么写

final CompiledScript script = ((Compilable) engine).compile(str);

final Bindings bindings = new SimpleBindings();

bindings.put("prod", true);

bindings.put("user", u);

final Boolean result = (Boolean) script.eval(bindings);

System.out.println(result);

返回true.

以上,如果从写配置文件的角度想,上面那么几个条件以及条件的优先级和组合会比较麻烦(感兴趣的可以试试看).

参考了

http://www.ticmy.com/?p=267

原文对于JSR223说得比这文更详细,可以去读一下.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值