在java应用中嵌入groovy
需求:
某高校博士录取分数线录取算法是这样的:
1、 硕博连读考生为外语45分以上(含45分,下同), 综合成绩(初试总分*0.7+复试分数*0.3)不低于60分;
2、 普通考生(经济管理学院除外)为外语45分以上,专业课60分以上,综合成绩(初试总分/3*0.7+复试分数*0.3)不低于60分;
3、 经济管理学院(001)考生外语55分以上,专业课60分以上,综合成绩(初试总分/3*0.7+复试分数*0.3)不低于60分。
这段算法简单、清楚,用java实现是a piece of cake,但是考虑到我们的招生系统是为全国很多高校服务的,每个学校的录取算法可能有不同,不能在代码里面写死,最好是能让用户自己配置这段算法。这么简单的算法(高校研究生招生明规则还是比较简单的,潜规则就不清楚了)如果用规则引擎,显然是杀鸡用牛刀了。在目前的需求而言,用脚本语言来处理可能是更好的选择。
java里面对脚本语言的支持很好,以前的话beanshell流行一点(印象中shark、jbpm里面都支持beanshell,不过很久没跟踪了,不知道现在这两大workflow engine的情况怎样了),现在groovy是越来越流行了,最新的groovy 1.6更号称性能有了巨大的改进。(http://www.infoq.com/articles/groovy-1-6),所以这里先尝试groovy。
g了一下,发现在应用里嵌入groovy有三种方式(参考http://groovy.codehaus.org/Embedding+Groovy)
第一种是比较传统的,通过GroovyShell的方式,跟用beanshell的方式差不多。
Binding binding = new Binding();binding.setVariable("foo", new Integer(2));GroovyShell shell = new GroovyShell(binding);Object value = shell.evaluate("println 'Hello World!'; x = 123; return foo * 10");assert value.equals(new Integer(20));assert binding.getVariable("x").equals(new Integer(123));
ClassLoader parent = getClass().getClassLoader();GroovyClassLoader loader = new GroovyClassLoader(parent);Class groovyClass = loader.parseClass(new File("src/test/groovy/script/HelloWorld.groovy"));// let's call some method on an instanceGroovyObject groovyObject = (GroovyObject) groovyClass.newInstance();Object[] args = {};groovyObject.invokeMethod("run", args);
import groovy.lang.Binding;import groovy.util.GroovyScriptEngine;String[] roots = new String[] { "/my/groovy/script/path" };GroovyScriptEngine gse = new GroovyScriptEngine(roots);Binding binding = new Binding();binding.setVariable("input", "world");gse.run("hello.groovy", binding);System.out.println(binding.getVariable("output"));
result=false;if(kslym=='12'){ zhcj=cszf*0.7+fscj*0.3; if(wgy>=45&&zhcj>=60)result=true;}else{ if(yxsm!='001'){ zhcj=cszf/3*0.7+fscj*0.3; if(wgy>=45&&ywk1>=60&&ywk2>=60&&zhcj>=60)result=true; } else{ zhcj=cszf/3*0.7+fscj*0.3; if(wgy>=55&&ywk1>=60&&ywk2>=60&&zhcj>=60)result=true; }}
public Boolean canPassed(DoctorRecruitScoreObj score) { Binding binding=new Binding(); binding.setVariable("kslym",score.getDoctorResignup().getKslym()); binding.setVariable("wgy",score.getEnglish()); binding.setVariable("zzll",score.getZzll()); binding.setVariable("ywk1",score.getCourseA()); binding.setVariable("ywk2",score.getCourseB()); binding.setVariable("cszf",score.getEnglish()+score.getZzll()+score.getCourseA()+score.getCourseB()); binding.setVariable("fscj",score.getCourseC()); binding.setVariable("yxsm",score.getDoctorResignup().getBkyxsm()); GroovyShell shell=new GroovyShell(binding); DoctorCuttingscore cuttingScore=getCuttingScore(); if(cuttingScore!=null) { shell.evaluate(cuttingScore.getRule()); return (Boolean)binding.getVariable("result"); } return false; }