spring + groovy 实现动态代码注入执行
2018-11-07 01:03
330 查看
昨天线上的代码调用一个远程的服务无缘无故不成功,又没加那么多日志,不好定位问题,好想在线上执行一下代码,打印点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方法
再写个test.python调用一个接口,其实就是读文件然后调用一下java的接口,要是不怕死,也可以在后台做一个可视化界面,加个执行按钮直接调用
#!/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
大功告成。尽情玩耍吧
相关文章推荐
- 动态改变Cron表达式,来实现动态执行Spring定时任务
- Spring动态对Quartz定时任务的管理,实现动态加载,停止的配置实例代码
- PHP实现动态执行代码的方法
- 如何在net中实现动态执行代码(js的eval)的功能?
- Spring Data JPA实现动态条件与范围查询实例代码
- IOC,依赖倒置 (理解) Spring依赖注入的实现技术是:动态代理
- 利用Spring Cloud Zuul实现动态路由示例代码
- Spring动态的注入Bean对象的实现方式,
- 在java main中执行spring注入代码
- Spring动态对Quartz定时任务的管理,实现动态加载,停止的配置实例代码
- spring 依赖注入原理代码实现
- IOC,依赖倒置 (理解) Spring依赖注入的实现技术是:动态代理
- Spring接口动态注入不同的实现类
- SpringMvc + Quarzt 动态执行任务实现过程
- 飘逸的Groovy,利用Groovy+windows执行计划 实现动态RunstatusDb2数据库
- Spring动态对Quartz定时任务的管理,实现动态加载,停止的配置实例代码
- Spring学习总结(16)——Spring AOP实现执行数据库操作前根据业务来动态切换数据源
- Spring学习总结(16)——Spring AOP实现执行数据库操作前根据业务来动态切换数据源
- Spring整合Quartz实现动态定时器的示例代码
- 通过Spring Boot配置动态数据源访问多个数据库的实现代码