zoukankan      html  css  js  c++  java
  • JAVA的嵌入式脚本开发(下)

    本文将分以下几个小节来学习:

    作用域

    上例中"ScriptContext.GLOBAL_SCOPE"就是作用域。

    ScriptContext的属性以及Bindings接口对象都有作用域属性。作用域有优先级,优先级高的作用域先查找。在获取属性或Bindings键值对时也可以设置要查找的作用域。

    ScriptContext中预定义的有两个作用域ScriptContext.ENGINE_SCOPE和ScriptContext.GLOBAL_SCOPE。前者表示的作用域对应的是当前脚本引擎,优先级高;后者表示的 作用域对应的是从同一引擎工厂中创建出来的所有脚本引擎对象,优先级低。

    package net.oseye;
    import java.io.*;
    import javax.script.*;
    
    public class ScriptTest {
    	public static void main(String[] args) throws ScriptException, IOException {
    		ScriptEngineManager factory=new ScriptEngineManager();
    		ScriptEngine se=factory.getEngineByName("JavaScript");
    		ScriptContext sc=se.getContext();
    		sc.setAttribute("name", "osEye", ScriptContext.ENGINE_SCOPE);
    		sc.setAttribute("name", "kevin", ScriptContext.GLOBAL_SCOPE);
    		se.eval("println(name)");
    		System.out.println(sc.getAttribute("name"));
    		System.out.println(sc.getAttribute("name",ScriptContext.GLOBAL_SCOPE));
    		Bindings bindings=se.getBindings(ScriptContext.ENGINE_SCOPE);
    		bindings.put("age", "10");
    		se.eval("println(age);");
    	}
    }

    输出:

    osEye
    osEye
    kevin
    10


    方法的调用

    如果脚本中的方法支持在在Java中调用,那么这种脚本引擎必须实现javax.script.Invocable接口。通过Invocable接口可以调用脚本中的顶层方法,也可以调用对象的成员方法。而JavaScript引擎是实现了Invocable接口的,我们来看看。

    package net.oseye;
    import javax.script.*;
    
    public class ScriptTest {
    	public static void main(String[] args) throws NoSuchMethodException, ScriptException {
    		ScriptEngineManager factory=new ScriptEngineManager();
    		ScriptEngine se=factory.getEngineByName("JavaScript");
    		//脚本顶层方法
    		se.eval("function greet(name){println('Hello,'+name);}");
    		Invocable invocable=(Invocable) se;
    		invocable.invokeFunction("greet", "kevin");
    		//脚本中对象的方法
    		se.eval("var obj={greet:function(name){return 'Hello,'+name;}}");
    		invocable=(Invocable)se;
    		Object object=se.get("obj");
    		Object res=invocable.invokeMethod(object, "greet", "kevin");
    		System.out.println(res);
    		
    	}
    }

    输出:

    Hello,kevin
    Hello,kevin

    invokeFunction和invokeMethod方法基本一样,只是invokeMethod要指定包含待调用方法的对象。

    如果脚本语言中实现了Java的接口,在Java中就可以调用脚本中方法,使与Java接口交互的应用不用关心接口是由什么方式来实现的,如:

    package net.oseye;
    import javax.script.*;
    
    public class ScriptTest {
    	public static void main(String[] args) throws NoSuchMethodException, ScriptException {
    		ScriptEngineManager factory=new ScriptEngineManager();
    		ScriptEngine se=factory.getEngineByName("JavaScript");
    		
    		se.eval("function sayHello(name){return 'Hello,'+name;}");
    		Invocable invocable=(Invocable) se;
    		Greet greet=invocable.getInterface(Greet.class);
    		String res=greet.sayHello("kevin");
    		System.out.println(res);
    		
    		se.eval("var obj={sayHello:function(name){return 'Hello,'+name;}}");
    		invocable=(Invocable) se;
    		greet=invocable.getInterface(se.get("obj"), Greet.class);
    		res=greet.sayHello("osEye");
    		System.out.println(res);
    		
    	}
    }
    interface Greet{
    	String sayHello(String name);
    }

    输出:

    Hello,kevin
    Hello,osEye


    编译脚本

    脚本语言一般都是解释执行的,如果需要执行的更快的可以把脚本编译。只要脚本引擎时间了javax.script.Compilable接口,就可以把脚本编译。

    package net.oseye;
    import javax.script.*;
    
    public class ScriptTest {
    	public static void main(String[] args) throws NoSuchMethodException, ScriptException {
    		ScriptEngineManager factory=new ScriptEngineManager();
    		ScriptEngine se=factory.getEngineByName("JavaScript");
    		if(se instanceof Compilable){
    			CompiledScript script=((Compilable) se).compile("println('kevin test compiel')");
    			script.eval();
    		}else{
    			System.out.println("脚本引擎不支持编译");
    		}		
    	}
    }

    当然这个Demo编译并没有任何意义,只是作为演示使用。一般把重复执行的脚本编译,以提高性能。

  • 相关阅读:
    UI 常用方法总结之--- UITableView
    UITextFiled 通知监听
    ios 本地通知
    AFNetworking 请求头的设置
    UI总结
    gitlab-server环境搭建
    redis 配置文件示例
    搭建spark集群
    kafka集群安装
    zookeeper集群搭建
  • 原文地址:https://www.cnblogs.com/zhaiqianfeng/p/4618265.html
Copyright © 2011-2022 走看看