자바 사용 ScriptEngine 동적 실행 코드(자바 몇 가지 동적 실행 코드 비교 첨부)

머리말
자바 프로젝트 에서 우 리 는 동적 실행 코드 에 대한 수요 가 많 거나 적 습 니 다.예 를 들 어:
  • 시스템 에 규칙 검증 수요 가 있 지만 규칙 이 자주 바뀐다
  • 코드 열 업데이트,열 복구
  • 필자 도 현재 참여 하고 있 는 프로젝트 에서 동적 실행 코드 에 대한 수 요 를 만 났 다.프로젝트 는 자동 심사 모듈 이 필요 하지만 심사 규칙 은 관련 서면 문서 에 따라 제정 된다.만약 에 자바 파일 에 쓰 여 죽 으 면 새로운 서면 파일 을 보 낼 때 시스템 이 정지 되 고 시스템 을 업데이트 해 야 계속 사용 할 수 있다.그 중에서 많은 불안정 요소 가 존재 한다.귀 찮 기도 하고.따라서 디자인 에 있어 서 동적 실행 코드 에 대한 수요 가 있다.다행히 이 수 요 는 하나의 양식 만 심사 할 뿐 시스템 의 조작 과 IO 조작 이 없고 입력 매개 변수 도 고정 되 어 있 습 니 다.
    필 자 는 인터넷 에 접속 하여 대량의 자 료 를 찾 아 보 았 는데 인터넷 에 대체적으로 세 가지 동적 집행 코드 방식 이 전해 지 는 것 을 발견 했다.필 자 는 전면적 인 비 교 를 통 해 그 중의 하 나 를 선택 했다.여기에 몇 가지 방법 을 아래 와 같이 열거한다.
    방법.
    1.JESL 동적 실행 식 사용
    참고JEXL 을 이용 하여 동적 표현 식 컴 파일 을 실현 합 니 다.
    JEXL 은 두 가지 순환 방식 을 지원 합 니 다.
    
    for(item : list) {
        x = x + item;
    }
    화해시키다
    
    while (x lt 10) {
        x = x + 2;
    }
    
    장점:자바 코드 를 동적 으로 실행 하고 자바 Function 을 호출 할 수 있 습 니 다.
    단점:Function 이 아 닌 하나의'표현 식'만 실행 할 수 있 기 때문에 문법 적 한계 가 많 습 니 다.하나의 Function 을 진정 으로 실행 하 는 것 이 아 닙 니 다.
    2.자바 동적 컴 파일 사용
    참고자바 코드 개선 동적 컴 파일
    동적 컴 파일 은 자바 의 꿈 이 었 습 니 다.자바 6 버 전부터 동적 컴 파일 을 지원 하기 시 작 했 습 니 다.실행 기간 에 자바 파일 을 직접 컴 파일 하고'class'를 실행 할 수 있 으 며 관련 입 출력 을 얻 을 수 있 으 며 관련 사건 도 감청 할 수 있 습 니 다.그러나 우리 가 가장 바 라 는 것 은 코드 를 정 하고 직접 컴 파일 한 다음 에 실행 하 는 것 이다.즉,공중 컴 파일 실행(on-the-fly)이다.
    장점:기능 이 강하 고 완전한 동적 집행 기능 을 진정 으로 실현 할 수 있 으 며 모든 시스템 기능 과 IO 작업 을 동적 으로 호출 할 수 있 습 니 다.
    단점:기능 이 강해 서 자바 파일 을 컴 파일 할 수 있 지만 실행 할 때 프레임 워 크 급 의 클래스 파일 을 바 꾸 기 는 어렵 지만 상기 방법 에 비해 지나 치지 않 습 니 다.모든 시스템 기능 과 IO 작업 을 동적 으로 호출 할 수 있 고 일반 코드 환경 과 격 리 되 지 않 아 프로젝트 에서 매우 심각 한 안전 위험 이 될 수 있 습 니 다.
    3.자바 스 크 립 트 엔진 사용
    자바 자체 테이프 의 ScriptEngine 을 사용 하 는 것 은 가장 완벽 한 자바 동적 실행 코드 방안 중 하나 라 고 할 수 있 습 니 다.(코드 열 업데이트 등 장면 을 고려 하지 않 음)ScriptEngine 인터넷 에 참고 할 수 있 는 대량의 자료 가 있 습 니 다.여 기 는 참고 자 료 를 첨부 하지 않 고 다음 JS Engine 을 사용 하 는 예 를 간단하게 제공 합 니 다.
    
    String regular="function regular(args1,args2,args3){................}";
    ScriptEngine engine = new ScriptEngineManager().getEngineByName("javascript");
    try {
    	engine.eval(regular);
    	if (engine instanceof Invocable) {
    		Invocable invoke = (Invocable) engine;
    		String result = (String) invoke.invokeFunction(
    				"regular", 
    				args1,
    				args2,
    				args3);
    		System.out.println(result);
    		} else {
    			System.out.println("error");
    		}
    	}
    } catch (ScriptException e) {
    	System.out.println("   runtime  :" + e.getMessage());
    }
    
    eval()를 사용 하여 JS 코드(JS function 포함)를 동적 으로 실행 한 다음 자바 의 Invoke 를 이용 하여 인 자 를 입력 하고 마지막 으로 반환 값 을 가 져 옵 니 다.
    장점:완전한 JS 방법 을 실행 하고 반환 값 을 가 져 올 수 있 습 니 다.가상 Context 에서 실행 하면 시스템 조작 과 IO 조작 을 호출 할 수 없고 매우 안전 합 니 다.여러 가지 최적화 방식 이 있 고 미리 컴 파일 할 수 있 으 며 컴 파일 한 후에 재 활용 할 수 있 으 며 효율 은 원생 자바 에 가깝다.ScriptEngine 인 터 페 이 스 를 실현 하 는 모든 언어 는 JS 뿐만 아니 라 Groovy,Ruby 등 언어 도 동적 으로 실행 할 수 있다.
    단점:시스템 과 IO 를 호출 할 수 없고 관련 js 라 이브 러 리 를 사용 할 수 없 으 며 js 의 표준 문법 만 사용 할 수 있 습 니 다.업데이트:scriptengine.put()를 사용 하여 자바 원생 Object 를 Context 에 전송 하여 호출 시스템 과 IO 등 작업 을 확대 할 수 있 습 니 다.
    일반적인 동적 실행 코드 수요 에 대해 서 는 마지막 방법 을 사용 하 는 것 을 권장 합 니 다.
    JDK 8 에서 자바 호출 자바 script 스 크 립 트 엔진 동적 정의 및 실행 코드
    
    import java.lang.*;
    import java.util.Arrays;
    import java.util.List;
     
    import javax.script.Invocable;
    import javax.script.ScriptEngine;
    import javax.script.ScriptEngineManager;
     
    public class ScriptEngineTest {
     
    public static void main(String[] args) throws Exception {
        ScriptEngineManager sem = new ScriptEngineManager();
        ScriptEngine engine = sem.getEngineByName("javascript");     //python or jython, 
     
    <pre name="code" class="html">   //         
       engine.put("msg", "just a test");
       //   user
       String str = "msg += '!!!';var user = {name:'tom',age:23,hobbies:['football','basketball']}; ";
       engine.eval(str);
     
       //         
       String msg = (String) engine.get("msg");
       String name = (String) engine.get("name");
       String[] hb = engine.get("hb");
       System.out.println(msg);
       System.out.println(name + ":" + hb[0]);
     
       //      
       engine.eval("function add (a, b) {c = a + b; return c; }");
     
        //      
        Invocable jsInvoke = (Invocable) engine;
     
      //      
     
      Object result1 = jsInvoke.invokeFunction("add", new Object[] { 10, 5 });
     
      System.out.println(result1);
     
      //      ,         
     
      Adder adder = jsInvoke.getInterface(Adder.class);
     
      int result2 = adder.add(10, 35);
     
      System.out.println(result2);
     
      //  run()  
     
      engine.eval("function run() {print('www.java2s.com');}");
     
      Invocable invokeEngine = (Invocable) engine;
     
      Runnable runner = invokeEngine.getInterface(Runnable.class);
      //       
     
      Thread t = new Thread(runner);
     
      t.start();
     
      t.join();
     
      //    java 
     
      String jsCode = "importPackage(java.util);
      var list2 = Arrays.asList(['A', 'B', 'C']); ";
     
      engine.eval(jsCode);
     
      List<String> list2 = (List<String>) engine.get("list2");
     
      for (String val : list2) { System.out.println(val);}
     
      }
     
    }
    스 크 립 트 엔진 은 동적 기능(예 를 들 어 플러그 인 메커니즘)을 실현 하기 위해 좋 은 확장 성 을 제공 합 니 다.
    엔진 인터페이스 에 대한 문서:
    ScriptEngine
    자바 가 ScriptEngine 을 사용 하 는 동적 실행 코드(자바 의 몇 가지 동적 실행 코드 비교)에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 자바 ScriptEngine 동적 실행 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 십시오.앞으로 많은 지원 을 바 랍 니 다!

    좋은 웹페이지 즐겨찾기