JSR223 Java使用指令碼引擎動態修改業務邏輯
本文來自圖靈社群 @fairjm 轉截請註明出處
偶爾會有一些業務需求是需要在動態改變線上程式碼的行為.一般的做法是使用個配置檔案,存在資料庫或者redis等儲存中,程式動態獲取之後解析並根據配置進行相應的操作.
在配置不復雜的情況下這樣的做法能夠滿足需求.但如果配置很複雜,或者配置的規則很多,那麼解析配置並執行就變成了一件很麻煩的事情.可能會引入一些解析器,或者Criteria
這樣的類.
如果這樣,那是不是嵌入一段程式碼動態載入執行會不會簡單點?
好在java本身就提供了這樣的機制,也就是JSR-223.
因為是開發使用的,所以最好還是用和java一樣的語法,方便現有開發,那選取的指令碼語言為groovy比較合適,畢竟能相容java語法.
搞起.
首先引入依賴:
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-jsr223</artifactId>
<version>2.4.7</version>
</dependency>
這邊用判斷使用者是否能夠訪問作為例子.
其中要考慮的使用者類如下(省略getter setter和構造器):
public class User {
private String userName;
private Long userId;
private Boolean isVip;
private Integer gender;
private Integer age;
現在的規則是如果是非生產環境返回true,會員返回true,使用者以test開頭(這只是例子 千萬別學)返回true 如果性別是男性並且大於18歲返回true(咦)
對應的groovy指令碼如下:
if (!prod) {
return true;
}
if (Boolean.TRUE.equals(user.getIsVip())) {
return true;
}
if (user.getUserName()?.startsWith("test")) {
return true;
}
if (user.getGender()?.equals(1) && user.getAge() != null && user.getAge() >= 18) {
return true;
}
return false;
?
表示式可以減少空判斷,因為groovy相容java,所以手工寫 != null
(比如age)也是可以的.
接來下執行:
// 獲取指令碼引擎
final ScriptEngineManager factory = new ScriptEngineManager();
final ScriptEngine engine = factory.getEngineByName("groovy");
// 讀取指令碼
String str;
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(
GroovyScriptTest.class.getResourceAsStream("/groovy-script")))) {
str = reader.lines().collect(Collectors.joining("\r\n"));
}
final User u = new User("fairjm", 1L, false, 1, 18);
// groovy的引擎是支援可編譯的所以直接這麼寫
final CompiledScript script = ((Compilable) engine).compile(str);
final Bindings bindings = new SimpleBindings();
bindings.put("prod", true);
bindings.put("user", u);
final Boolean result = (Boolean) script.eval(bindings);
System.out.println(result);
返回true.
以上,如果從寫配置檔案的角度想,上面那麼幾個條件以及條件的優先順序和組合會比較麻煩(感興趣的可以試試看).
參考了
http://www.ticmy.com/?p=267
原文對於JSR223說得比這文更詳細,可以去讀一下.
相關文章
- 使用 Drools 規則引擎實現業務邏輯
- 風控規則引擎(一):Java 動態指令碼Java指令碼
- 用java實現業務邏輯Java
- [java程式碼]業務邏輯查詢幫助類Java
- 使用Windows指令碼進行邏輯備份Windows指令碼
- [原始碼解析] Pytorch 如何實現後向傳播 (3)---- 引擎動態邏輯原始碼PyTorch
- expdp 邏輯備份指令碼指令碼
- Oracle邏輯備份指令碼Oracle指令碼
- 幽默:什麼是業務邏輯程式碼?
- 業務邏輯學習!
- 使用Java實現一個JS指令碼引擎JavaJS指令碼
- cocos-creator 指令碼邏輯-1指令碼
- SPA PLM 核心業務邏輯
- 業務邏輯漏洞和cs
- groovy之動態指令碼的使用指令碼
- 使用expect執行動態指令碼指令碼
- Java動態指令碼Groovy,高階啊!Java指令碼
- 使用開源API Logic Server實現業務邏輯模型自動化APIServer模型
- 實現拼團業務邏輯
- 強業務邏輯抽象API介面抽象API
- bp靶場業務邏輯漏洞
- Windows邏輯備份-EXPDP(保留5天內邏輯備份)批處理指令碼Windows指令碼
- 使用 AI 進行 - 視覺化 - 業務&系統邏輯AI視覺化
- java邏輯控制Java
- java取反邏輯Java
- [原始碼解析] TensorFlow 分散式環境(6) --- Master 動態邏輯原始碼分散式AST
- [原始碼解析] TensorFlow 分散式環境(7) --- Worker 動態邏輯原始碼分散式
- BLoc模式在React中使用-業務邏輯元件的獨立使用BloC模式React元件
- Java 中使用動態程式碼Java
- shell動態指令碼和pl/sql動態指令碼的比較指令碼SQL
- Java動態指令碼Groovy讀取配置檔案Java指令碼
- Python寫業務邏輯的幾個編碼原則Python
- WINDOWS下部署ORACLE邏輯匯出備份指令碼WindowsOracle指令碼
- 多使用者商城系統原始碼_業務邏輯功能思維導圖_OctShop原始碼
- 狀態機解決複雜邏輯及使用
- 修改 jetstream laravel/fortify 登入邏輯Laravel
- APP攻防--安卓逆向&資料修改&邏輯修改&檢視修改APP安卓
- 前端業務程式碼配置化處理條件判斷邏輯前端