Embed groovy in java application

need:
The doctoral admission score admission algorithm of a certain university is as follows:
1. Candidates for the master's and doctoral program must have a foreign language score of 45 points or above (including 45 points, the same below), and a comprehensive score (total score in the preliminary test * 0.7 + retest score * 0.3) of not less than 60 points;
2. Ordinary candidates (except the School of Economics and Management) must have a foreign language score of 45 or above, a professional course score of 60 or above, and a comprehensive score (preliminary test total score/3*0.7+retest score*0.3) of not less than 60 point;
3. Candidates from the School of Economics and Management (001) have a foreign language score of 55 or above, a professional course score of 60 or above, and a comprehensive score (preliminary test total score/3*0.7+retest score*0.3) of not less than 60 points.

This algorithm is simple and clear. Implementing it in Java is a piece of cake. However, considering that our admissions system serves many universities across the country, the admissions algorithm of each school may be different. It cannot be hard-coded into the code. It is best to allow users to configure this algorithm themselves. For such a simple algorithm (the explicit rules for college graduate admissions are relatively simple, but the hidden rules are not clear), if you use a rule engine, it is obviously overkill. In terms of current needs, using a scripting language may be a better choice.

Java has good support for scripting languages. In the past, beanshell was more popular (I have the impression that both shark and jbpm support beanshell, but I haven’t followed it for a long time. I don’t know what the two major workflow engines are now. What's going on?), groovy is becoming more and more popular now, and the latest groovy 1.6 claims to have huge improvements in performance. ([url]http://www.infoq.com/articles/groovy-1-6[/url]), so try groovy here first.

After some research, I found that there are three ways to embed groovy in applications (refer to [url]http://groovy.codehaus.org/Embedding+Groovy[/url])

The first one is more traditional, using GroovyShell, which is similar to using 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));


The second way is to dynamically load groovy classes through GroovyClassLoader, and then use groovy classes directly. The reason this is possible is that every Groovy class is a legal Java class after compilation. This method doesn't make much sense. Why not directly integrate the Java compiler and dynamically load the Java class after compiling the Java class? hehe.
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 instance
GroovyObject groovyObject = (GroovyObject) groovyClass.newInstance();
Object[] args = {};
groovyObject.invokeMethod("run", args);


The third way is to use GroovyScriptEngine. If you want to provide the most complete scripting support in your application, GroovyScriptEngine is the best choice. GSE will perform dependency detection, that is, if a script that a certain script depends on is modified, the entire script tree will be recompiled and reloaded.
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"));


Our application only needs to simply execute a script for the time being, so we chose the first method. Throw groovy-all-1.6.0.jar in the embeddable directory into the class path and configure the script in the interface (see attached picture
[img]/upload/attachment/96851/0182191c-963a-35f2-ac7b-8ce4c85f2b3c.png[/img]
):
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;
}
}


How to determine whether doctoral candidates are online in the background:
    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;
}


A brief explanation: I hate the use of Pinyin abbreviations for variable naming, but many data structures in university research departments are named with Pinyin abbreviations, so the scripts here can only be in line with them. The script ultimately has to be revised by the teacher.

Done!

The execution efficiency is still good. I don’t know whether groovy evaluates the same script and caches it in a similar way to executing sql. The data here is relatively small, only a few hundred entries. After all, there are still relatively few doctoral candidates, usually only a few hundred. However, after a few years, the employment rate of master's degree candidates may no longer be good, and everyone is encouraged to continue taking Ph.D. examinations. Will the number of Ph.D. candidates be in the thousands? Let’s see if we need to optimize the program then, haha.

Guess you like

Origin blog.csdn.net/fireshort/article/details/83389966