Java動態(tài)腳本Groovy
1.Groovy特性
可將java
代碼在Groovy
腳本動態(tài)編碼、代碼被修改達到不重啟服務的目的(類似于熱部署)
2.核心涉及
ClassLoader
:就是類的裝載器,它使JVM可以動態(tài)的載入Java類,JVM并不需要知道從什么地方(本地文件、網絡等)載入Java類,這些都由ClassLoader
完成。GroovyClassLoader
:動態(tài)地加載一個腳本并執(zhí)行它的行為。GroovyClassLoader是一個定制的類裝載器,負責解釋加載Java類中用到的Groovy類。
3.Java與Groovy轉換
第一步:引入Groovy依賴
<!--Groovy腳本依賴--> <dependency> <groupId>org.codehaus.groovy</groupId> <artifactId>groovy</artifactId> <version>2.5.14</version> </dependency>
第二步:創(chuàng)建interface接口聲明方法
public interface CallAnalysis { default void load() { } }
第三步:在resources目錄下創(chuàng)建.groovy文件
package groovy import com.example.groovy.testgroovy.task.CallAnalysis import groovy.util.logging.Slf4j @Slf4j class CallAnalysisImpl implements CallAnalysis{ @Override void load() { log.info("我被Groovy腳本加載...") } }
第四步:創(chuàng)建Groovy腳本裝載類,動態(tài)解析腳本為Class
package com.example.groovy.testgroovy.task; import groovy.lang.GroovyClassLoader; public class GroovyUtils { private final static ClassLoader classLoader = GroovyUtils.class.getClassLoader();//獲取當前類裝載器 //ClassLoader:就是類的裝載器,它使JVM可以動態(tài)的載入Java類,JVM并不需要知道從什么地方(本地文件、網絡等)載入Java類,這些都由ClassLoader完成。 public final static GroovyClassLoader groovyClassLoader = new GroovyClassLoader(classLoader); //GroovyClassLoader:負責在運行時編譯groovy源代碼為Class的工作,從而使Groovy實現(xiàn)了將groovy源代碼動態(tài)加載為Class的功能。 /** * . * 獲取實例化對象 * @param script groovy腳本內容 * @param <T> * @return * @throws IllegalAccessException * @throws InstantiationException */ public static <T> T instanceTaskGroovyScript(String script) throws IllegalAccessException, InstantiationException { Class taskClz = groovyClassLoader.parseClass(script); T instance = (T) taskClz.newInstance(); return instance; } }
第五步:讀取腳本內容,執(zhí)行腳本
package com.example.groovy.testgroovy.task; import lombok.extern.slf4j.Slf4j; import org.apache.commons.io.FileUtils; import org.springframework.stereotype.Component; import java.io.File; import java.io.IOException; @Slf4j @Component public class CallAnalysisGroovyTask { /** * . * 讀取腳本內容 * * @return */ public static String getGroovy() { String context = ""; try { String path = "E:\\IDEAFile\\testgroovy\\src\\main\\resources\\groovy\\CallAnalysisImpl.groovy"; context = FileUtils.readFileToString(new File(path));//將腳本內容轉為字符串 } catch (IOException e) { log.error("file is not found[{}]", e); } return context; } /** * . * 執(zhí)行groovy腳本 * * @param script */ public static void execGroovy(String script) { try { CallAnalysis objClass = GroovyUtils.instanceTaskGroovyScript(script);//獲取實例對象 objClass.load();//調用腳本方法 } catch (Exception t) { log.error("execGroovy file {} error", script); } } /** * . * main方法 * @param args */ public static void main(String[] args) { System.out.println("=================="); CallAnalysisGroovyTask task = new CallAnalysisGroovyTask(); String script = task.getGroovy();//獲取腳本 execGroovy(script);//實例化腳本,執(zhí)行方法 System.out.println("=================="); } }
4.Groovy特性驗證
利用Groovy
腳本特性,不重啟服務,實時修改數(shù)據(jù)
第一步:將之前Groovy腳本數(shù)據(jù)修改。存于數(shù)據(jù)庫表中,動態(tài)加載腳本
@Slf4j class CallAnalysisImpl implements CallAnalysis { private int anInt = 10; private int bnInt = 10; @Override void load() { log.info("當前類:[{}]", this.getClass().getName()) log.info("我被Groovy腳本加載...") log.info("計算結果:[{}]", (anInt + bnInt)) } }
第二步:數(shù)據(jù)庫表中:添加、查詢Groovy腳本,動態(tài)加載執(zhí)行
/** * . * 讀取腳本,進行入庫操作 * * @return */ @GetMapping("/saveScript") public String saveScript() { String scriptStr = callAnalysisGroovyTask.getGroovy(); Script script = new Script();//實體類對象 script.setScript(scriptStr);//腳本內容 script.setRuleId("1");//規(guī)則id script.setScriptName("演示一");//腳本名稱 service.save(script); return "添加成功"; } /** * . * 從數(shù)據(jù)庫表中,動態(tài)獲取腳本 * * @param ruleId 規(guī)則id * @return 腳本內容 */ @GetMapping("/groovy") public String groovy(final String ruleId) { Script scr = scriptService.findScriptByRuleId(ruleId);//根據(jù)規(guī)則id查詢 String scriptStr = scr.getScript(); callAnalysisGroovyTask.execGroovy(scriptStr); return scriptStr; }
添加結果:
?查詢結果、控制臺執(zhí)行結果:
第三步:多次修改表數(shù)據(jù)值,查看執(zhí)行結果
5.總語
目的達成,可見在不重啟服務時,多次修改數(shù)據(jù),腳本內容都會被動態(tài)加載。此處只是簡單舉例驗證,可自行擴展
到此這篇關于Java動態(tài)腳本Groovy的文章就介紹到這了,更多相關Java動態(tài)腳本Groovy內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Spring Cloud Feign請求添加headers的實現(xiàn)方式
這篇文章主要介紹了Spring Cloud Feign請求添加headers的實現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-04-04如何實現(xiàn)Java中一個簡單的LinkedList
LinkedList與ArrayList都是List接口的具體實現(xiàn)類。下面將介紹如何實現(xiàn)一個簡單的LinkedList,具有很好的參考價值,下面跟著小編一起來看下吧2017-02-02Assert.assertEquals的使用方法及注意事項說明
這篇文章主要介紹了Assert.assertEquals的使用方法及注意事項說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-05-05解決FeignClient發(fā)送post請求異常的問題
這篇文章主要介紹了FeignClient發(fā)送post請求異常的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-07-07