强大的groovy框架,可以帮我们解决很多问题,今天我们聚焦其中一个场景简单介绍其功能。
有时我们遇生产数据问题,我们在修复时可能直接写sql比较复杂,又没有现成的运维接口可以使用,这时怎么处理呢,一般情况下就是现开发代码上线后调用运维接口,这就涉及到要发包的过程了,如果我们不想发包能不能有什么办法处理类似场景呢,我们来看下groovy能帮我们做什么?
不建议经常使用此类功能处理生产问题
我们先写一个接口做新增用户的动作
@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {
@Autowired
private TmpUserMapper tmpUserMapper;
@RequestMapping(value = "/add", method = RequestMethod.POST)
public ResponseVo<Integer> addUser(@RequestBody TmpUser user){
try {
return ResponseVo.success(tmpUserMapper.insert(user));
}catch (Exception e){
log.error("创建用户失败: {}", e);
return ResponseVo.fail(e.getMessage());
}
}
}
我们使用postman调用该接口传入一条叫“小王”的数据
id | name | age |
---|---|---|
4 | 小王 | 25 |
如果我们替换成groovy帮我实现是什么样子呢,上代码
@RestController
@RequestMapping("/groovy")
@Slf4j
public class GroovyController {
@Autowired
private ApplicationContext applicationContext;
@RequestMapping(value = "/omnipotent", method = RequestMethod.POST)
public ResponseVo<String> groovy(@RequestBody String content){
try {
GroovyClassLoader groovyClassLoader = new GroovyClassLoader(this.getClass().getClassLoader());
CompilerConfiguration compilerConfiguration = new CompilerConfiguration();
compilerConfiguration.setSourceEncoding("utf-8");
Binding groovyBinding = new Binding();
applicationContext.getBeansOfType(Object.class).forEach(groovyBinding::setVariable);
GroovyShell groovyShell = new GroovyShell(groovyClassLoader, groovyBinding, compilerConfiguration);
Script script = groovyShell.parse(content);
return ResponseVo.success(String.valueOf(script.run()));
} catch (Exception e) {
log.error("groovy脚本执行失败: {}", e);
return ResponseVo.fail(e.getMessage());
}
}
}
我们通过postman传入groovy脚本并返回新增的主键id
查看数据库生成的数据
id | name | age |
---|---|---|
4 | 小王 | 25 |
5 | 小张 | 26 |
所以,你可以在脚本中编写带逻辑的代码
像groovy、aviator原理类似,都是根据脚本动态生成字节码文件后执行,这类博文比较多,可以自行检索。