@(JAVA總結)java
在網上查了資料發現,java有三種方式調用groovy腳本。可是真正在實際的服務器環境中,嵌入groovy腳本每每須要知足下面的條件:緩存
只有知足了上面的這些要求,才能安心的將其嵌入到現有的Java後臺服務中。
下面就來具體探討下具體實現的步驟。服務器
其實,GroovyScriptEngine類就已經提供了上面所說的功能。
主要使用GroovyScriptEngine.loadScriptByName來讀取腳本,loadScriptByName方法內部提供了緩存功能,在讀取groovy腳本的時候,會優先從緩存中讀取,若是緩存中沒有的話,纔去讀取腳本,以下:
測試
在後面的測試後,會用到下面的java類和groovy腳本。this
該類用於測試傳遞Java對象到Groovy腳本中code
public class Person { public String name; public String address; public Integer age; public Person(String name, String addr, Integer age){ this.name = name; this.address = addr; this.age = age; } public String toString(){ return String.format("[Person: name:%s, address:%s, age:%s]", name,address, age); } }
下面腳本中的兩個方法用於測試方法的無參調用和帶參調用orm
def helloWithoutParam(){ println "start to call helloWithoutParam!" return "success, helloWithoutParam"; } def helloWithParam(person, id){ println "start to call helloWithParam, param{person:" + person + ", id:" + id + "}"; return "success, helloWithParam"; }
public static void testGroovy2(){ try { Class scriptClass = groovyScriptEngine.loadScriptByName("hello2.groovy"); GroovyObject scriptInstance = (GroovyObject)scriptClass.newInstance(); Object ret = scriptInstance.invokeMethod("helloWithoutParam", null); System.out.println("testGroovy2:" + ret); } catch (Exception e) { e.printStackTrace(); System.out.println("Exception e="+e.toString()); } }
執行結果:
start to call helloWithoutParam!
testGroovy2: success, helloWithoutParam對象
@SuppressWarnings({ "rawtypes" }) public static void testGroovy3(){ try { Person person = new Person("wchi", "nanjing", 30); Class scriptClass = groovyScriptEngine.loadScriptByName("hello2.groovy"); GroovyObject scriptInstance = (GroovyObject)scriptClass.newInstance(); Object ret = scriptInstance.invokeMethod("helloWithParam", new Object[]{person,"lxi"}); System.out.println("testGroovy3:" + ret); } catch (Exception e) { e.printStackTrace(); System.out.println("Exception e="+e.toString()); } }
返回結果:
start to call helloWithParam, param{person:[Person: name:wchi, address:nanjing, age:30], id:lxi}
testGroovy3: success, helloWithParamip
能夠將上面的代碼封裝成公用類,這樣就方便不少,以下:字符串
public class GroovyCommonUtil { private static final Logger log = LoggerFactory.getLogger(GroovyCommonUtil.class); //該變量用於指明groovy腳本所在的父目錄 static String root[]=new String[]{"bin/groovy/"}; static GroovyScriptEngine groovyScriptEngine; static{ try { groovyScriptEngine=new GroovyScriptEngine(root); } catch (IOException e) { e.printStackTrace(); } } /** * 用於調用指定Groovy腳本中的指定方法 * @param scriptName 腳本名稱 * @param methodName 方法名稱 * @param params 方法參數 * @return */ @SuppressWarnings({ "rawtypes"}) public Object invokeMethod(String scriptName, String methodName, Object... params) throws Exception{ Object ret = null; Class scriptClass = null; GroovyObject scriptInstance = null; try { scriptClass = groovyScriptEngine.loadScriptByName(scriptName); scriptInstance = (GroovyObject)scriptClass.newInstance(); } catch (ResourceException | ScriptException | InstantiationException | IllegalAccessException e1) { log.warn("加載腳本["+scriptName+"]出現異常", e1); throw new Exception("加載腳本"+scriptName+"失敗"); } try { ret = (String)scriptInstance.invokeMethod(methodName, params); } catch (IllegalArgumentException e) { log.warn("執行方法" + methodName + "參數出現異常, 參數爲" + params, e); throw new Exception("調用方法[" + methodName + "]失敗,因參數不合法"); } catch(Exception e){ log.warn("執行方法" + methodName + "出現異常", e); throw new Exception("調用方法[" + methodName + "]失敗"); } return ret; }
使用上面的公用類,改寫的測試代碼以下:
/** * 測試沒有參數的方法調用 */ public static void testGroovyWithoutParam(){ String result = (String)GroovyCommonUtil.invokeMethod("hello2.groovy", "helloWithoutParam"); System.out.println("testGroovy4: " + result + "\n"); } /** * 測試攜帶參數的方法調用 */ public static void testGroovyWithParam(){ Person person = new Person("wchi", "nanjing", 30); String result = (String)GroovyCommonUtil.invokeMethod("hello2.groovy", "helloWithParam", person, "testGroovy4"); System.out.println("testGroovy4: " + result + "\n"); }