We already know how to execute the scripting language in Java, today, with groovy as a chestnut, and see How to use the spring container in a script.
Bindings
The simplest way is to throw ApplicationContext directly into the scriptengine context, which is bindings inside, so the script can be used directly ApplicationContext.getBean
to get the beans inside the container.
import java.util.Random;publicclass Foo { privateint i; publicintgetI() { return i; } publicbar() { System.out.println("hello Foo."); thisnew Random().nextInt(); returnthis; }}
ImportOrg.springframework.context.ApplicationContext;ImportOrg.springframework.context.support.ClassPathXmlApplicationContext;ImportJavax.script.Bindings;ImportJavax.script.ScriptContext;ImportJavax.script.ScriptEngine;ImportJavax.script.ScriptEngineManager;ImportJava.util.HashMap;ImportJava.util.Map; Public class Main { Public Static void Main(string[] args)throwsException {ApplicationContext context =NewClasspathxmlapplicationcontext ("Spring-beans.xml"); map<string, object> params =NewHashmap<string, object> (); Params.put ("SC", context); Scriptenginemanager SEM =NewScriptenginemanager (); ScriptEngine SE = sem.getenginebyname ("Groovy"); Bindings Bindings = Se.createbindings (); Bindings.putall (params); Se.setbindings (bindings, scriptcontext.engine_scope); String Text ="foo = Sc.getbean (\" foo\ "); Foo.bar ();"; System.out.println ((Foo) se.eval (text)). Geti ()); Bindings.clear (); }}
Output
hello Foo.54704882
It is also stated that the return value of the last statement in the script will be ScriptEngine#eval
the return value.
DRY
If the spring bean is used in this way, many sc.getBean
of these duplicate codes will appear. Lazy is a programmer's virtue, in order to liberate productivity, we can again optimize the next.
In the agreed manner (COC), when the variable name starts with an __
underscore of two, it means that the variable is a spring bean, and the character following the underscore is the bean's name. Then we just have to make a regular replacement before throwing it to the scripting engine to execute it.
Public class Main { Public Static void Main(string[] args)throwsException {ApplicationContext context =NewClasspathxmlapplicationcontext ("Spring-beans.xml"); map<string, object> params =NewHashmap<string, object> (); String Bindingname_ac ="_springcontext"; Params.put (Bindingname_ac, context); Scriptenginemanager SEM =NewScriptenginemanager (); ScriptEngine SE = sem.getenginebyname ("Groovy"); Bindings Bindings = Se.createbindings (); Bindings.putall (params); Se.setbindings (bindings, scriptcontext.engine_scope); String Text ="__foo.bar (); foo = __foo; Foo.geti (); "; String Replacedtext = Text.replaceall ("__ (\\w*)", bindingname_ac+". Getbean (\" $1\ ")"); System.out.println (Replacedtext); System.out.println (Se.eval (Replacedtext)); Bindings.clear (); }}
The output is as follows,
_springContext.getBean("foo").bar(); foo = _springContext.getBean("foo"); foo.getI();hello Foo.-885362561
The scope of the binding only Scriptcontext#engine_scope and Scriptcontext#global_scope these two, in order to prevent the binding of the mutual pollution, after the execution of the script is still a bindings.clear()
little insurance.
Resources
- http://docs.oracle.com/javase/tutorial/essential/regex/
Scripting Java (ii): Using the Spring container