我写的
类1
class GroovyScriptFactory {
private static Map<String, Class<Script>> scriptCache = new HashMap<>();
private GroovyClassLoader classLoader = new GroovyClassLoader();
private static GroovyScriptFactory factory = new GroovyScriptFactory();
/**
* 设置为单例模式
*/
private GroovyScriptFactory() {
}
static GroovyScriptFactory getInstance() {
return factory;
}
private Class<Script> getScript(String key) {
// 压缩脚本节省空间
String encodeStr = EncryptUtil.SHA256(key);
if (scriptCache.containsKey(encodeStr)) {
return scriptCache.get(encodeStr);
} else {
// 脚本不存在则创建新的脚本
@SuppressWarnings("unchecked")
Class<Script> scriptClass = classLoader.parseClass(key);
scriptCache.put(encodeStr, scriptClass);
return scriptClass;
}
}
private Object run(Class<Script> script, Binding binding) {
Script scriptObj = InvokerHelper.createScript(script, binding);
Object result = scriptObj.run();
// 每次脚本执行完之后,一定要清理掉内存
classLoader.clearCache();
return result;
}
Object scriptGetAndRun(String key, Binding binding) {
return run(getScript(key), binding);
}
}
类2
@Slf4j
@Accessors(chain = true)
public class ExpressParser {
private final GroovyScriptFactory groovy = GroovyScriptFactory.getInstance();
/**
* 表达式解析
* <p>
* 我们这里只返回Boolean结果
*
* @param importPath 脚本依赖的其他的jar包路径
* @param script 待解析的表达式脚本
* @return true=解析为true, false=解析结果为false
*/
public Boolean parse(String importPath, String script, NeoMap dataMap) {
try {
Object result = groovy.scriptGetAndRun(importPath + "\n" + script, new Binding(dataMap));
if (null == result) {
return false;
}
return (Boolean) result;
} catch (Throwable e) {
log.error("表达式执行失败,script={}, bind={}", script, dataMap.toFastJsonString());
}
return false;
}
/**
* 表达式解析
* <p>
* 我们这里只返回Boolean结果
*
* @param script 待解析的表达式脚本
* @return true=解析为true, false=解析结果为false
*/
public Boolean parse(String script, NeoMap dataMap) {
return parse("", script, dataMap);
}
}
其他开源的
private static final GroovyShell SHELL = new GroovyShell();
... 其他代码...
private Object evaluate(final String expression) {
Script script;
if (SCRIPTS.containsKey(expression)) {
script = SCRIPTS.get(expression);
} else {
script = SHELL.parse(expression);
SCRIPTS.put(expression, script);
}
return script.run();
}