日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java动态执行逻辑_动态执行代码逻辑

發布時間:2025/3/20 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java动态执行逻辑_动态执行代码逻辑 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

動態執行邏輯的方法據我所知有一下兩種方式

QLExpress

Groovy

QLExpress

QLExpress是阿里開源的動態腳本執行的項目。 由阿里的電商業務規則、表達式(布爾組合)、特殊數學公式計算(高精度)、語法分析、腳本二次定制等強需求而設計的一門動態腳本引擎解析工具。 在阿里集團有很強的影響力,同時為了自身不斷優化、發揚開源貢獻精神,于2012年開源。

這種方案在配置上感覺不太方便,原因是沒有IDE支持、某些JAVA語法不支持。。。

Groovy

來著百度百科

Groovy 是 用于Java虛擬機的一種敏捷的動態語言,它是一種成熟的面向對象編程語言,既可以用于面向對象編程,又可以用作純粹的腳本語言。使用該種語言不必編寫過多的代碼,同時又具有閉包和動態語言中的其他特性。

Groovy是JVM的一個替代語言(替代是指可以用 Groovy 在Java平臺上進行 Java 編程),使用方式基本與使用 Java代碼的方式相同,該語言特別適合與Spring的動態語言支持一起使用,設計時充分考慮了Java集成,這使 Groovy 與 Java 代碼的互操作很容易。(注意:不是指Groovy替代java,而是指Groovy和java很好的結合編程。

原理

通過Groovy提供的GroovyClassLoader把源代碼動態加載編譯成Class,Class再實例化成對象

動手實現

依賴

org.codehaus.groovy

groovy

3.0.0-rc-1

cn.hutool

hutool-all

5.0.3

創建動態腳本工廠,inject方法用于擴展。

package cn.dhbin.dynamic;

import cn.hutool.core.util.StrUtil;

import cn.hutool.crypto.SecureUtil;

import groovy.lang.GroovyClassLoader;

import java.util.concurrent.ConcurrentHashMap;

/**

* 動態腳本工廠

* 作用:

* 通過字符串源碼生成Class

* Class -> 實例

*

* @author donghaibin

* @date 2019/11/19

*/

public class DynamicFactory {

/**

* 單例

*/

private static DynamicFactory dynamicFactory = new DynamicFactory();

/**

* groovy類加載器

*/

private GroovyClassLoader groovyClassLoader = new GroovyClassLoader();

/**

* 緩存Class

*/

private ConcurrentHashMap> classCache = new ConcurrentHashMap<>();

/**

* 獲取單例

*

* @return 實例

*/

public static DynamicFactory getInstance() {

return dynamicFactory;

}

/**

* 加載創建實例,prototype

*

* @param codeSource 源代碼

* @return 實例

* @throws Exception 異常

*/

public IScript loadNewInstance(String codeSource) throws Exception {

if (StrUtil.isNotBlank(codeSource)) {

Class> aClass = getCodeSourceClass(codeSource);

if (aClass != null) {

Object instance = aClass.newInstance();

if (instance != null) {

if (instance instanceof IScript) {

this.inject((IScript) instance);

return (IScript) instance;

} else {

throw new IllegalArgumentException(StrUtil.format("創建實例失敗,[{}]不是IScript的子類", instance.getClass()));

}

}

}

}

throw new IllegalArgumentException("創建實例失敗,instance is null");

}

/**

* code text -> class

* 通過類加載器生成class

*

* @param codeSource 源代碼

* @return class

*/

private Class> getCodeSourceClass(String codeSource) {

String md5 = SecureUtil.md5(codeSource);

Class> aClass = classCache.get(md5);

if (aClass == null) {

aClass = groovyClassLoader.parseClass(codeSource);

classCache.putIfAbsent(md5, aClass);

}

return aClass;

}

/**

* 對script對象處理

*

* @param script {@link IScript}

*/

public void inject(IScript script) {

// to do something

}

}

定義腳本模板

package cn.dhbin.dynamic;

/**

* 腳本接口,所有腳本實現該接口的{@link IScript#run(String)}方法

*

* @author donghaibin

* @date 2019/11/19

*/

public interface IScript {

/**

* 具體邏輯

*

* @param param 參數

* @return 執行結果

*/

String run(String param);

}

腳本執行器

package cn.dhbin.dynamic;

import java.util.concurrent.ConcurrentHashMap;

/**

* @author donghaibin

* @date 2019/11/19

*/

public class ScriptExecutor {

/**

* 緩存實例

*/

private ConcurrentHashMap objCache = new ConcurrentHashMap<>();

/**

* 執行腳本

*

* @param id 實例Id

* @return 運行結果

*/

public String run(String id, String param) {

IScript script = objCache.get(id);

if (script == null) {

throw new IllegalArgumentException("未找到實例, id = [" + id + "]");

} else {

return script.run(param);

}

}

/**

* 注冊實例

*

* @param id 實例id

* @param script 實例

* @return 返回前一個實例,如果為null,則是新插入

*/

public IScript register(String id, IScript script) {

return objCache.put(id, script);

}

/**

* 移除實例

*

* @param id 實例id

* @return 移除的實例

*/

public IScript remove(String id) {

return objCache.remove(id);

}

}

到這里,就基本實現了腳本的加載-實例化-執行。下面測試

編寫腳本

package cn.dhbin.dynamic;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

/**

* @author donghaibin

* @date 2019/11/19

*/

public class SimpleScript implements IScript{

private static final Logger log = LoggerFactory.getLogger(SimpleScript.class);

@Override

public String run(String param) {

log.info("輸入的參數是:[{}]", param);

log.info("你好世界");

return "hello world";

}

}

測試用例

package com.pig4cloud.pig.sms.dynamic;

import lombok.extern.slf4j.Slf4j;

import org.junit.jupiter.api.Test;

/**

* @author donghaibin

* @date 2019/11/19

*/

@Slf4j

class DynamicFactoryTest {

@Test

void runWithExecutor() throws Exception {

DynamicFactory dynamicFactory = DynamicFactory.getInstance();

ScriptExecutor executor = new ScriptExecutor();

String codeSource = "package cn.dhbin.dynamic;\n" +

"\n" +

"import org.slf4j.Logger;\n" +

"import org.slf4j.LoggerFactory;\n" +

"\n" +

"/**\n" +

" * @author donghaibin\n" +

" * @date 2019/11/19\n" +

" */\n" +

"public class SimpleScript implements IScript{\n" +

"\n" +

"\tprivate static final Logger log = LoggerFactory.getLogger(SimpleScript.class);\n" +

"\n" +

"\t@Override\n" +

"\tpublic String run(String param) {\n" +

"\t\tlog.info(\"輸入的參數是:[{}]\", param);\n" +

"\t\tlog.info(\"你好世界\");\n" +

"\t\treturn \"hello world\";\n" +

"\t}\n" +

"\n" +

"}\n";

IScript script = dynamicFactory.loadNewInstance(codeSource);

String id = "1";

executor.register(id, script);

for (int i = 0; i < 10; i++) {

String result = executor.run(id, "abc");

log.info("結果:[{}]", result);

}

}

@Test

void runWithoutExecutor() throws Exception{

DynamicFactory dynamicFactory = DynamicFactory.getInstance();

String codeSource = "package cn.dhbin.dynamic;\n" +

"\n" +

"import org.slf4j.Logger;\n" +

"import org.slf4j.LoggerFactory;\n" +

"\n" +

"/**\n" +

" * @author donghaibin\n" +

" * @date 2019/11/19\n" +

" */\n" +

"public class SimpleScript implements IScript{\n" +

"\n" +

"\tprivate static final Logger log = LoggerFactory.getLogger(SimpleScript.class);\n" +

"\n" +

"\t@Override\n" +

"\tpublic String run(String param) {\n" +

"\t\tlog.info(\"輸入的參數是:[{}]\", param);\n" +

"\t\tlog.info(\"你好世界\");\n" +

"\t\treturn \"hello world\";\n" +

"\t}\n" +

"\n" +

"}\n";

for (int i = 0; i < 10; i++) {

IScript script = dynamicFactory.loadNewInstance(codeSource);

String result = script.run("abc");

log.info("結果:[{}]", result);

}

}

}

執行結果

11:19:32.243 [main] INFO cn.dhbin.dynamic.SimpleScript - 輸入的參數是:[abc]

11:19:32.255 [main] INFO cn.dhbin.dynamic.SimpleScript - 你好世界

11:19:32.255 [main] INFO cn.dhbin.dynamic.DynamicFactoryTest - 結果:[hello world]

11:19:32.255 [main] INFO cn.dhbin.dynamic.SimpleScript - 輸入的參數是:[abc]

11:19:32.255 [main] INFO cn.dhbin.dynamic.SimpleScript - 你好世界

11:19:32.255 [main] INFO cn.dhbin.dynamic.DynamicFactoryTest - 結果:[hello world]

11:19:32.255 [main] INFO cn.dhbin.dynamic.SimpleScript - 輸入的參數是:[abc]

11:19:32.255 [main] INFO cn.dhbin.dynamic.SimpleScript - 你好世界

11:19:32.255 [main] INFO cn.dhbin.dynamic.DynamicFactoryTest - 結果:[hello world]

11:19:32.255 [main] INFO cn.dhbin.dynamic.SimpleScript - 輸入的參數是:[abc]

11:19:32.255 [main] INFO cn.dhbin.dynamic.SimpleScript - 你好世界

11:19:32.255 [main] INFO cn.dhbin.dynamic.DynamicFactoryTest - 結果:[hello world]

11:19:32.255 [main] INFO cn.dhbin.dynamic.SimpleScript - 輸入的參數是:[abc]

11:19:32.255 [main] INFO cn.dhbin.dynamic.SimpleScript - 你好世界

11:19:32.255 [main] INFO cn.dhbin.dynamic.DynamicFactoryTest - 結果:[hello world]

11:19:32.255 [main] INFO cn.dhbin.dynamic.SimpleScript - 輸入的參數是:[abc]

11:19:32.255 [main] INFO cn.dhbin.dynamic.SimpleScript - 你好世界

11:19:32.255 [main] INFO cn.dhbin.dynamic.DynamicFactoryTest - 結果:[hello world]

11:19:32.255 [main] INFO cn.dhbin.dynamic.SimpleScript - 輸入的參數是:[abc]

11:19:32.256 [main] INFO cn.dhbin.dynamic.SimpleScript - 你好世界

11:19:32.256 [main] INFO cn.dhbin.dynamic.DynamicFactoryTest - 結果:[hello world]

11:19:32.256 [main] INFO cn.dhbin.dynamic.SimpleScript - 輸入的參數是:[abc]

11:19:32.256 [main] INFO cn.dhbin.dynamic.SimpleScript - 你好世界

11:19:32.256 [main] INFO cn.dhbin.dynamic.DynamicFactoryTest - 結果:[hello world]

11:19:32.256 [main] INFO cn.dhbin.dynamic.SimpleScript - 輸入的參數是:[abc]

11:19:32.256 [main] INFO cn.dhbin.dynamic.SimpleScript - 你好世界

11:19:32.256 [main] INFO cn.dhbin.dynamic.DynamicFactoryTest - 結果:[hello world]

11:19:32.256 [main] INFO cn.dhbin.dynamic.SimpleScript - 輸入的參數是:[abc]

11:19:32.256 [main] INFO cn.dhbin.dynamic.SimpleScript - 你好世界

11:19:32.256 [main] INFO cn.dhbin.dynamic.DynamicFactoryTest - 結果:[hello world]

兩個用例執行的結果都一樣,區別就是一個使用了執行器。這樣做的目的是提高運行效率,執行器緩存了實例對象,不用每次執行都實例化。

總結

Groovy這種方案其實是從xxl-job這個定時任務項目中提取出來的。它還擴展了Spring的幾個注解,能從Spring的容器中加載Bean并使用。項目鏈接: https://gitee.com/xuxueli0323...

思考

通過groovy動態加載Class,再結合Spring的生命周期,是否可以實現動態添加Bean?是否可以實現動態添加Controller?

總結

以上是生活随笔為你收集整理的java动态执行逻辑_动态执行代码逻辑的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 免费在线观看一区二区三区 | 美女四肢被绑在床扒衣 | 超碰69| 精品国产a | 污视频网站免费观看 | 特级特黄刘亦菲aaa级 | 福利免费在线观看 | 男人av网 | 欧美一区二不卡视频 | 免费在线激情视频 | 在线日韩一区二区 | 精品日韩在线 | 欧美另类xxx| 久久国产视频网站 | 少妇被躁爽到高潮 | 欧美亚洲激情 | 91视频免费看片 | 精品一级少妇久久久久久久 | 激情a| 久久久综合色 | 国产无毛片 | 外国黄色录像 | 精品一区二区三区四区五区六区 | 久久久久亚洲av无码专区喷水 | 国产免费激情 | 高清三区 | 在线免费观看麻豆 | 婷色| 美女毛片网站 | 毛片美女 | 黄色特级大片 | 扒开jk护士狂揉免费 | 青少年xxxxx性开放hg | 色婷婷综合久久久中文字幕 | 在线观看自拍 | 欧美在线观看不卡 | 欧美在线网站 | 操小妹影院 | 国产亚州av | 高清av在线 | 欧美精品网站 | 欧美国产精品一区 | 亚洲欧美在线成人 | 欧美午夜精品 | 日韩一区二区在线免费观看 | 亚洲欧美另类综合 | 91av视频免费观看 | 污污的视频网站在线观看 | 久久视频免费 | 祥仔视觉av | 懂色aⅴ一区二区三区免费 国产精品99在线观看 | 狠狠躁夜夜躁人 | 国产精品热久久 | 男人av资源网 | 大肉大捧一进一出好爽视频动漫 | 卡通动漫精品一区二区三区 | 日韩成人区 | 日韩在线视频播放 | 国产制服91一区二区三区制服 | 亚洲av成人精品日韩在线播放 | 国产又黄又嫩又滑又白 | 亚洲第一偷拍 | 国产不卡在线 | 亚洲欧洲在线播放 | 大奶在线观看 | 日本一区二区视频 | 四虎三级 | 男女洗澡互摸私密部位视频 | 日韩精品视频三区 | 久久久亚洲av波多野结衣 | 日韩欧美在线观看一区二区三区 | 日本美女视频一区 | gay男互凵gay男同偷精 | 午夜在线观看av | 国产精品无码电影在线观看 | 日本三级理论片 | 图片区亚洲色图 | 黑帮大佬和我的三百六十五天 | 久久久久人妻一区精品 | 少妇免费看 | 国产人妻人伦精品1国产丝袜 | 色婷婷影院 | 青青操在线 | 51吃瓜网今日 | 人妻在线一区二区 | 国产亚洲精品久久久久动 | 91九色视频在线 | 久热最新 | 午夜在线一区二区三区 | 国产一区二区三区四区 | 亚洲高清视频免费观看 | 亚洲午夜av在线 | 91久久精品国产91久久性色tv | 波多野结衣欲乱上班族 | 日本男女激情视频 | 看免费毛片 | 吻胸摸激情床激烈视频 | 欧美黄色免费视频 | 色av中文字幕 |