我写的

类1

  1. class GroovyScriptFactory {
  2. private static Map<String, Class<Script>> scriptCache = new HashMap<>();
  3. private GroovyClassLoader classLoader = new GroovyClassLoader();
  4. private static GroovyScriptFactory factory = new GroovyScriptFactory();
  5. /**
  6. * 设置为单例模式
  7. */
  8. private GroovyScriptFactory() {
  9. }
  10. static GroovyScriptFactory getInstance() {
  11. return factory;
  12. }
  13. private Class<Script> getScript(String key) {
  14. // 压缩脚本节省空间
  15. String encodeStr = EncryptUtil.SHA256(key);
  16. if (scriptCache.containsKey(encodeStr)) {
  17. return scriptCache.get(encodeStr);
  18. } else {
  19. // 脚本不存在则创建新的脚本
  20. @SuppressWarnings("unchecked")
  21. Class<Script> scriptClass = classLoader.parseClass(key);
  22. scriptCache.put(encodeStr, scriptClass);
  23. return scriptClass;
  24. }
  25. }
  26. private Object run(Class<Script> script, Binding binding) {
  27. Script scriptObj = InvokerHelper.createScript(script, binding);
  28. Object result = scriptObj.run();
  29. // 每次脚本执行完之后,一定要清理掉内存
  30. classLoader.clearCache();
  31. return result;
  32. }
  33. Object scriptGetAndRun(String key, Binding binding) {
  34. return run(getScript(key), binding);
  35. }
  36. }

类2

  1. @Slf4j
  2. @Accessors(chain = true)
  3. public class ExpressParser {
  4. private final GroovyScriptFactory groovy = GroovyScriptFactory.getInstance();
  5. /**
  6. * 表达式解析
  7. * <p>
  8. * 我们这里只返回Boolean结果
  9. *
  10. * @param importPath 脚本依赖的其他的jar包路径
  11. * @param script 待解析的表达式脚本
  12. * @return true=解析为true, false=解析结果为false
  13. */
  14. public Boolean parse(String importPath, String script, NeoMap dataMap) {
  15. try {
  16. Object result = groovy.scriptGetAndRun(importPath + "\n" + script, new Binding(dataMap));
  17. if (null == result) {
  18. return false;
  19. }
  20. return (Boolean) result;
  21. } catch (Throwable e) {
  22. log.error("表达式执行失败,script={}, bind={}", script, dataMap.toFastJsonString());
  23. }
  24. return false;
  25. }
  26. /**
  27. * 表达式解析
  28. * <p>
  29. * 我们这里只返回Boolean结果
  30. *
  31. * @param script 待解析的表达式脚本
  32. * @return true=解析为true, false=解析结果为false
  33. */
  34. public Boolean parse(String script, NeoMap dataMap) {
  35. return parse("", script, dataMap);
  36. }
  37. }

其他开源的

  1. private static final GroovyShell SHELL = new GroovyShell();
  2. ... 其他代码...
  3. private Object evaluate(final String expression) {
  4. Script script;
  5. if (SCRIPTS.containsKey(expression)) {
  6. script = SCRIPTS.get(expression);
  7. } else {
  8. script = SHELL.parse(expression);
  9. SCRIPTS.put(expression, script);
  10. }
  11. return script.run();
  12. }