上一篇简答说了如何判断有任务动态添加、删除或更新,归于一点就是监听文件的变化,判断目录下的Groovy文件是否有新增删除和改变,从而断定是否有任务的变动;java
接下来的问题就比较明显了,当任务变动以后,就须要从新加载任务了,即如何动态的编译并执行Groovy文件呢?git
相关系列博文:github
<!--more-->网络
要想动态加载类,能够怎么办?若是对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文件便可,使用也比较简单ui
@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对象以后,借助反射来建立对象编码
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&公众号
知识星球