小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

在Java中使用腳本語言 javax.script探秘

 quasiceo 2015-01-14

在Java中使用腳本語言 javax.script探秘

2010-07-01 09:29 邊城客棧 JavaEye的博客 字號:T | T
一鍵收藏,隨時查看,分享好友!

Java 6對腳本語言的支持來自JSR223規(guī)范,對應(yīng)的包是javax.script。今天我們就一起來看看Java混合編程的一個嘗試,在Java中使用腳本語言進(jìn)行編程。

AD:WOT2015 互聯(lián)網(wǎng)運維與開發(fā)者大會 熱銷搶票

之前我們提到Java,總說其最大的特點是跨平臺,是一次編寫到處運行。但最近幾年,Java領(lǐng)域最大的變化就是基于JVM的語言正在開始流行,Java已經(jīng)進(jìn)入了混合編程時代。今天我們要向您介紹的就是Java在多語言方面的一個嘗試,在Java中使用腳本語言。(關(guān)于Java多語言編程請參考51CTO的專題:《Java程序員的未來 走向混合編程時代》)。

1、可用的腳本引擎

Java 6提供對執(zhí)行腳本語言的支持,這個支持來自于JSR223規(guī)范,對應(yīng)的包是javax.script。默認(rèn)情況下,Java 6只支持JavaScript腳本,它底層的實現(xiàn)是Mozilla Rhino,它是個純Java的JavaScript實現(xiàn)。可以通過下面的代碼列出當(dāng)前環(huán)境中支持的腳本引擎:

  1. ScriptEngineManager manager = new ScriptEngineManager();  
  2.         ListScriptEngineFactory> factories = manager.getEngineFactories();  
  3.         for (ScriptEngineFactory f : factories) {  
  4.             System.out.println(  
  5.                     "egine name:"+f.getEngineName()+  
  6.                     ",engine version:"+f.getEngineVersion()+  
  7.                     ",language name:"+f.getLanguageName()+  
  8.                     ",language version:"+f.getLanguageVersion()+  
  9.                     ",names:"+f.getNames()+  
  10.                     ",mime:"+f.getMimeTypes()+  
  11.                     ",extension:"+f.getExtensions());  
  12.         } 

輸出結(jié)果:egine name:Mozilla Rhino,engine version:1.6 release 2,language name:ECMAScript,language version:1.6,names:[js, rhino, JavaScript, javascript, ECMAScript, ecmascript],mime:[application/javascript, application/ecmascript, text/javascript, text/ecmascript],extension:[js]。

可以看到,Java內(nèi)置只支持JavaScript一種腳本。但是,只要遵循 JSR223,便可以擴展支持多種腳本語言,可以從https://scripting.dev./上查找當(dāng)前已被支持的腳本的第三方庫。

2、hello script

接下來給出在Java中使用JavaScript的Hello world示例:

  1. ScriptEngineManager manager = new ScriptEngineManager ();  
  2.         ScriptEngine engine = manager.getEngineByName ("js");  
  3.         String script = "print ('hello script')";  
  4.         try {  
  5.             engine.eval (script);  
  6.         } catch (ScriptException e) {  
  7.             e.printStackTrace();  
  8.         } 

使用的API還是很簡單的,ScriptEngineManager是ScriptEngine的工廠,實例化該工廠的時候會加載可用的所有腳本引擎。從工廠中創(chuàng)建ScriptEngine可以使用getEngineByName、getEngineByExtension或 getEngineByMimeType來得到,只要參數(shù)名字能對上。執(zhí)行腳本調(diào)用eval方法即可(效果等同于JavaScript中的eval)。

3、傳遞變量

可以向腳本中傳遞變量,使得Java代碼可以和腳本代碼交互,示例如下:

  1. ScriptEngineManager manager = new ScriptEngineManager();  
  2.         ScriptEngine engine = manager.getEngineByName("js");  
  3.         engine.put("a"4);  
  4.         engine.put("b"6);  
  5.         try {  
  6.             Object maxNum = engine.eval("function max_num(a,b){return (a>b)?a:b;}max_num(a,b);");  
  7.             System.out.println("max_num:" + maxNum);  
  8.         } catch (Exception e) {  
  9.             e.printStackTrace();  
  10.         } 

輸出內(nèi)容:max_num:6

對于上面put的變量,它作用于自身engine范圍內(nèi),也就是ScriptContext.ENGINE_SCOPE,put 的變量放到一個叫Bindings的Map中,可以通過 engine.getBindings(ScriptContext.ENGINE_SCOPE).get(“a”);得到put的內(nèi)容。和ENGINE_SCOPE相對,還有個ScriptContext.GLOBAL_SCOPE 作用域,其作用的變量是由同一ScriptEngineFactory創(chuàng)建的所有ScriptEngine共享的全局作用域。

4、動態(tài)調(diào)用

上面的例子中定義了一個JavaScript函數(shù)max_num,可以通過Invocable接口來多次調(diào)用腳本庫中的函數(shù),Invocable接口是 ScriptEngine可選實現(xiàn)的接口。下面是個使用示例:

  1. ScriptEngineManager manager = new ScriptEngineManager();  
  2.         ScriptEngine engine = manager.getEngineByName("js");  
  3.         try {  
  4.             engine.eval("function max_num(a,b){return (a>b)?a:b;}");  
  5.             Invocable invoke = (Invocable) engine;  
  6.             Object maxNum = invoke.invokeFunction("max_num",4,6);  
  7.             System.out.println(maxNum);  
  8.             maxNum = invoke.invokeFunction("max_num"7,6);  
  9.             System.out.println(maxNum);  
  10.         } catch (Exception e) {  
  11.             // TODO: handle exception  
  12.         } 

上面的invokeFunction,第一個參數(shù)調(diào)用的腳本函數(shù)名,后面跟的可變參數(shù)是對應(yīng)的腳本函數(shù)參數(shù)。

Invocable還有個很酷的功能,就是動態(tài)實現(xiàn)接口,它可以從腳本引擎中得到Java Interface 的實例;也就是說,可以定義個一個Java接口,其實現(xiàn)是由腳本完成。以上面的例子為例,定義接口JSLib,該接口中的函數(shù)和JavaScript中的函數(shù)簽名保持一致:

  1. public interface JSLib {  
  2.        public int max_num(int a,int b);  
  3.    } 

調(diào)用示例:

  1. ScriptEngineManager manager = new ScriptEngineManager();  
  2.         ScriptEngine engine = manager.getEngineByName("js");  
  3.         try {  
  4.             engine.eval("function max_num(a,b){return (a>b)?a:b;}");  
  5.             Invocable invoke = (Invocable) engine;  
  6.             JSLib jslib = invoke.getInterface(JSLib.class);  
  7.             int maxNum = jslib.max_num(4,6);  
  8.             System.out.println(maxNum);  
  9.         } catch (Exception e) {  
  10.             // TODO: handle exception  
  11.         } 

5、使用Java對象

可以在JavaScript中使用Java代碼,這確實是很酷的事情。在Rhino中,可以通過importClass導(dǎo)入一個類,也可以通過importPackage導(dǎo)入一個包,也可以直接使用全路經(jīng)的類。在創(chuàng)建對象時,new也不是必須的。示例代碼如下:

  1. ScriptEngineManager manager = new ScriptEngineManager();  
  2.         ScriptEngine engine = manager.getEngineByName("js");  
  3.         try {  
  4.             String script = "var list = java.util.ArrayList();list.add(\"kafka0102\");print(list.get(0));";  
  5.             engine.eval(script);  
  6.         } catch (Exception e) {  
  7.             e.printStackTrace();  
  8.         } 

6、編譯執(zhí)行

腳本引擎默認(rèn)是解釋執(zhí)行的,如果需要反復(fù)執(zhí)行腳本,可以使用它的可選接口Compilable來編譯執(zhí)行腳本,以獲得更好的性能,示例代碼如下:

  1. ScriptEngineManager manager = new ScriptEngineManager();  
  2.         ScriptEngine engine = manager.getEngineByName("js");  
  3.         try {  
  4.             Compilable compEngine = (Compilable) engine;  
  5.             CompiledScript script = compEngine.compile("function max_num(a,b){return (a>b)?a:b;}");  
  6.             script.eval();  
  7.             Invocable invoke = (Invocable) engine;  
  8.             Object maxNum = invoke.invokeFunction("max_num",4,6);  
  9.             System.out.println(maxNum);  
  10.         } catch (Exception e) {  
  11.             e.printStackTrace();  
  12.         } 

7、總結(jié)

除了上面提到的特性,腳本引擎還有一些不錯的功能,比如可以執(zhí)行腳本文件,可以由多線程異步執(zhí)行腳本等功能。引入腳本引擎,可以對一些配置擴展和業(yè)務(wù)規(guī)則做更強大而靈活的支持,也方便使用者選擇自己熟悉的腳本語言來編寫業(yè)務(wù)規(guī)則等。

【責(zé)任編輯:red7 TEL:(010)68476606】

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多