上一篇簡答說了如何判斷有任務動態添加、刪除或更新,歸於一點就是監聽文件的變化,判斷目錄下的Groovy文件是否有新增刪除和改變,從而斷定是否有任務的變動;java
接下來的問題就比較明顯了,當任務變動以後,就須要從新加載任務了,即如何動態的編譯並執行Groovy文件呢?git
相關係列博文:github
要想動態加載類,能夠怎麼辦?若是對JVM有必定了解的朋友可能知道,自定義一個ClassLoader,能夠實現從文件/網絡/DB/Jar包中讀取class文件,而Groovy,動態語言,簡單來講就是.groovy文件能夠直接運行,那麼咱們編碼中要怎麼玩?網絡
讓我本身來實現Groovy文件的編譯執行,目前基本上是看不到啥但願的,因此果斷的藉助第三方工具類加載Groovy文件框架
pom文件添加依賴工具
<dependency> <groupId>org.codehaus.groovy</groupId> <artifactId>groovy-all</artifactId> <version>2.4.3</version> </dependency>
直接利用上面jar包中提供的GroovyCalssLoader來加載Groovy文件便可,使用也比較簡單學習
@Slf4j public class GroovyCompile { @SuppressWarnings("unchecked") public static <T> T compile(File codeSource, Class<T> interfaceType, ClassLoader classLoader) throws CompileTaskScriptException { try { GroovyClassLoader loader = new GroovyClassLoader(classLoader); Class clz = loader.parseClass(codeSource); // 接口校驗 if (!interfaceType.isAssignableFrom(clz)) { throw new CompileTaskScriptException("illegal script type!"); } return (T) clz.newInstance(); } catch (IOException e) { log.error("load code from {} error! e: {}", codeSource, e); throw new CompileTaskScriptException("load code from " + codeSource + " error!"); } catch (CompileTaskScriptException e) { throw e; } catch (Exception e) { log.error("initial script error! codePath: {}, e: {}", codeSource, e); throw new CompileTaskScriptException( "initial script error! clz: " + codeSource + " msg: " + e.getMessage()); } } }
上面看着挺多,關鍵地方就三行,編譯爲class對象以後,藉助反射來建立對象ui
GroovyClassLoader loader = new GroovyClassLoader(classLoader); Class clz = loader.parseClass(codeSource); return (T) clz.newInstance();
另外還有一行,也能夠順帶湊一眼,判斷一個class是否爲另外一個class的子類,用的是編碼
interfaceType.isAssignableFrom(clz)
而判斷某個對象是否爲某類的子類用的則是 instance of
設計
上面既然提供了一個工具類,那麼接上篇的獲取變更文件以後,獲取File對象,藉此拿到任務對象,就比較清晰了
@Slf4j public class ScriptLoadUtil { public static ITask loadScript(File file) { try { return GroovyCompile.compile(file, ITask.class, ScriptLoadUtil.class.getClassLoader()); } catch (CompileTaskScriptException e) { log.error("un-expect error! e: {}", e); return null; } } }
本篇內容比較簡單,知識點也沒多少,一個是利用GroovyClassLoader
來編譯Groovy文件並獲取實例;另外一個就是如何判斷一個class是否爲另外一個class的子類
還有一個隱藏的點上面沒有說,那就是上面的GroovyCompile文件中,每次加載Groovy文件時,都是新建立了一個GroovyClassLoader,並由它來加載並實例Groovy任務,那麼問題來了
針對上面的問題,暫不給出答案,後面再說
博文:
項目:
一灰灰的我的博客,記錄全部學習和工做中的博文,歡迎你們前去逛逛
盡信書則不如,已上內容,純屬一家之言,因我的能力有限,不免有疏漏和錯誤之處,如發現bug或者有更好的建議,歡迎批評指正,不吝感激
小灰灰Blog&公衆號
知識星球