您现在的位置是:首页 > 文章详情

spring + groovy 实现动态代码注入执行

日期:2018-11-06点击:534

昨天线上的代码调用一个远程的服务无缘无故不成功,又没加那么多日志,不好定位问题,好想在线上执行一下代码,打印点log看看
于是想着怎么动态执行点java代码,忽然想起以前玩过的groovy,于是搞起来

大概思路是这样,写一个控制器,接收一段代码,动态执行,然后返回执行结果,切记,做好权限控制,免得杯具

没想到实现起来异常简单

1、gradle.build加入groovy依赖

compile "org.codehaus.groovy:groovy:2.5.3"

2、写个工具类,方便拿到spring上下文对象,这个很常见

import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; public class SpringContextUtils implements ApplicationContextAware { static ApplicationContext context; @Override public void setApplicationContext(ApplicationContext context) throws BeansException { SpringContextUtils.context = context; } public static ApplicationContext getContext() { return context; } public static void autowireBean(Object bean) { context.getAutowireCapableBeanFactory().autowireBean(bean); } public static <T> T getBean(Class<T> clazz) { return context.getBean(clazz); } } 

3、写个控制器

import com.ruizton.util.SpringContextUtils; import groovy.lang.GroovyClassLoader; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.lang.reflect.Method; @RestController public class GroovyController { @RequestMapping("/runScript") public Object runScript(String script) throws Exception { if (script != null) { // 这里其实就是groovy的api动态的加载生成一个Class,然后反射生成对象,然后执行run方法,最后返回结果 // 最精华的地方就是SpringContextUtils.autowireBean,可以实现自动注入bean, Class clazz = new GroovyClassLoader().parseClass(script); Method run = clazz.getMethod("run"); Object o = clazz.newInstance(); SpringContextUtils.autowireBean(o); Object ret = run.invoke(o); return ret; } else { return "no script"; } } } 

上面是java的全部内容了,接下来就是调用了

首先准备写个test.groovy代码

import org.springframework.beans.factory.annotation.Autowired class Foo { @Autowired FooService fooService; Object run() { // do something def f = fooService.findById(38); if (f != null) { return f.name } return null } }

不写类直接写代码块也是可以的
test.groovy

def sum = 1 + 2 return "sum = " + sum

上面代码也会生成一个Class对象,里面的代码默认在run方法下面,所以控制器哪里都是调用的run方法

再写个python调用一个接口,其实就是读文件然后调用一下java的接口,要是不怕死,也可以在后台做一个可视化界面,加个执行按钮直接调用

test.py

#!/usr/bin/python import requests def read(filename): f = open(filename,'r') file = f.read() f.close() return file res = requests.post('http://127.0.0.1/runScript.html', data = { 'script': read('test.groovy') }) print res.text
$ chmod +x test.py $ ./test.py

大功告成。尽情玩耍吧

原文链接:https://yq.aliyun.com/articles/665345
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章