随着业务的不断发展,产品的持续迭代,个性化需求越来越多,例如多维度的条件查询、流程业务的节点流转规则等,对此常见的代码实现方式通常有以下几种
(1)Hard Code:if else枚举所有的情形,这样的代码实现方式显得臃肿,而且对代码的侵入性极大
(2)策略模式实现:针对不同的情形设计不同的Handler进行处理,策略模式相对于枚举处理业务相对比较灵活,然而没增加一种业务就必须增加一个雷进行处理,如果两种业务相似性较强,往往难以进行有效的代码复用
(3)Groovy规则引擎:利用groovy引擎动态执行脚本,业务更加灵活
- 引入依赖
- Controller层
@RestController
@RequestMapping(value = "/groovy")
public class GroovyController {
@Autowired
private GroovyExpressionService expressionService;
@PostMapping("/evaluate")
public Object evaluate(@RequestParam String expression) {
return expressionService.evaluateExpression(expression);
}
}
- 构建参数map,加入bean与groovy表达式执行过程中需要用到的参数
@Service
public class GroovyExpressionService {
@Autowired
private BusinessService businessService;
@Autowired
private GroovyEngineService groovyEngineService;
public Object evaluateExpression(String expression) {
Map map = Maps.newHashMap();
enrichGroovyBeans(map);
enrichVariables(map);
return groovyEngineService.execute(expression, map);
}
private void enrichVariables(Map map) {
map.put("firstNumber",10);
map.put("secondNumber", 20);
}
private void enrichGroovyBeans(Map map) {
map.put("businessService", businessService);
}
}
- 调用groovy引擎进行表达式的计算
@Service
public class GroovyEngineService {
private static GroovyShell groovyShell;
static {
CompilerConfiguration cfg = new CompilerConfiguration();
cfg.setScriptBaseClass(MyBasicScript.class.getName());
groovyShell = new GroovyShell(cfg);
}
public Object execute(String expression, Map context) {
Script script = groovyShell.parse(expression);
Binding binding = new Binding();
context.forEach(binding::setVariable);
script.setBinding(binding);
return script.run();
}
}
@Component
public class MyBasicScript extends Script {
@Override
public Object run() {
return null;
}
}
- 测试
上述demo只是针对运算加法进行了处理,后续有了新的业务需求,诸如减法、乘法、乘法、最小二乘等其他统计计算需求时,只需要根据规则引擎设计相应的函数计算即可,灵活方便



