我写的
类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();}
