一、編譯腳本
ClassLoader parent =ClassLoader.getSystemClassLoader();
GroovyClassLoader loader =new GroovyClassLoader(parent);
Class<?> clazz = loader.parseClass(codeContent);
ConcurrentHashMap<String, Object> toolMap = new ConcurrentHashMap<>();
toolMap.put(groovyClass.getSimpleName(), groovyClass);
GroovyObject clazzObj =(GroovyObject)clazz.newInstance();
System.out.println(clazzObj.invokeMethod("test","str"));
注意:需要注意的是,通過看groovy的創建類的地方,就能發現,每次執行的時候,都會新生成一個class文件,這樣就會導致JVM的perm區持續增長,進而導致FullGCc問題,解決辦法很簡單,
就是腳本文件變化了之后才去創建文件,之前從緩存中獲取即可,緩存的實現可以采用簡單的CourrentHashMap或者使用之前文章提到的EhCache(同時可以設置緩存有效期,降低服務器壓力)
二、執行
public static Object invokeClass(String className, String methodName, Object... params){
if (StringUtils.isBlank(className) || StringUtils.isBlank(methodName)){
log.error("method name or class name is null!");
return null;
}
Class clz = (Class)GlobalTool.toolMap.get(className);
Method[] methods = clz.getMethods();
for (Method m : methods){
Object result = null;
Method method = null;
if (m.getName().equals(methodName)){
Object o = null;
try {
o = clz.newInstance();
try {
if (m.getParameterCount() == 0 && params.length == 0){
method = clz.getMethod(m.getName());//返回一個 Method 對象,該對象反映此 Class 對象所表示的類或接口的指定已聲明方法
try {
result= method.invoke(o);//靜態方法第一個參數可為null,第二個參數為實際傳參
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}else {
method = clz.getMethod(m.getName(), m.getParameterTypes());//返回一個 Method 對象,該對象反映此 Class 對象所表示的類或接口的指定已聲明方法
try {
if (params.length == 0){
log.error("params are illegal!");
return null;
}
if (m.getParameterTypes().length != params.length){
continue;
}else if (m.getParameterTypes().length == params.length){
log.info("method and param combine successful!");
result= method.invoke(o, params);//靜態方法第一個參數可為null,第二個參數為實際傳參
}
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}else {
continue;
}
return result;
}
return null;
}