spring项目中嵌入groovy脚本

网上搜java嵌入groovy有很多文章,一般是使用GroovyClassLoader来实现。
我们的项目嵌入groovy主要是用它作为事件处理程序使用类似简单的规则引擎,因为事件处理程序变动可能比较多,groovy脚本可以动态加载,脚本更新后,java部分只有重新重新加载,这样就运行最新的脚本了。
先看下我们需要的脚本格式:

导入包:

com.xxx.FooService
com.xxx.Context 

代码:


@Autowired
FooService fooService

void handle(Context context) { 
    // 具体业务代码。。。
}

导入包类似java的 import。
Autowired是导入spring application context定义的bean。
代码里面的方法void handle(Context context) 是固定的,项目里面有个接口EventHandle,这个就是它的实现,这样后面我们根据groovy脚本动态的生成一个EventHandle接口的实现类。事件触发时调用的就是这个实现类。

整个过程是这样的:
读取 导入类,到一个String[](根据回车换行分割), 顺便添加关键字 import。



<!-- lang: java -->
GroovyClassLoader classLoader = new GroovyClassLoader(classLoader);
....
getEventHandleClass(..) {
    StringBuilder sb 
    sb.append("class ").append("EventHandle_").append("_").append(SEQ.incrementAndGet()).append(" implements EventHandle {\n");
        sb.append(script);
        sb.append("}\n");
        String text = sb.toString();
        return classLoader.parseClass(text);
}

这样就得到了一个类型为Class 的class对象。
然后就要得到类的实例:


EventHandle handle = BeanUtils.instantiateClass(getEventHandleClass(..));
applicationContext.getAutowireCapableBeanFactory().autowireBean(handle);
return handle;

applicationContext autowireBean 是利用spring容器实现脚本里面的Autowired注入。
有了实例就可以直接调用了。
为了提高效率这个实例可以缓存,只是当脚本发生改变时才需要重新生成实例。

你可能感兴趣的:(spring,groovy,嵌入)