最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java中動(dòng)態(tài)規(guī)則的實(shí)現(xiàn)方式示例詳解

 更新時(shí)間:2020年08月25日 10:17:47   作者:阿凡盧  
這篇文章主要介紹了Java中動(dòng)態(tài)規(guī)則的實(shí)現(xiàn)方式,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

背景

業(yè)務(wù)系統(tǒng)在應(yīng)用過程中,有時(shí)候要處理“經(jīng)常變化”的部分,這部分需求可能是“業(yè)務(wù)規(guī)則”,也可能是“不同的數(shù)據(jù)處理邏輯”,這部分動(dòng)態(tài)規(guī)則的問題,往往需要可配置,并對(duì)性能和實(shí)時(shí)性有一定要求。

Java不是解決動(dòng)態(tài)層問題的理想語言,在實(shí)踐中發(fā)現(xiàn)主要有以下幾種方式可以實(shí)現(xiàn):

  • 表達(dá)式語言(expression language)
  • 動(dòng)態(tài)語言(dynamic/script language language),如Groovy
  • 規(guī)則引擎(rule engine)

表達(dá)式語言

Java Unified Expression Language,簡(jiǎn)稱JUEL,是一種特殊用途的編程語言,主要在JavaWeb應(yīng)用程序用于將表達(dá)式嵌入到web頁面。Java規(guī)范制定者和Java Web領(lǐng)域技術(shù)專家小組制定了統(tǒng)一的表達(dá)式語言。JUEL最初包含在JSP2.1規(guī)范JSR-245中,后來成為Java EE 7的一部分,改在JSR-341中定義。

主要的開源實(shí)現(xiàn)有:OGNLMVEL,SpELJUEL,Java Expression Language (JEXL),JEval,Jakarta JXPath等。

這里主要介紹在實(shí)踐中使用較多的MVEL、OGNL和SpEL。

OGNL(Object Graph Navigation Library)

在Struts 2 的標(biāo)簽庫(kù)中都是使用OGNL表達(dá)式訪問ApplicationContext中的對(duì)象數(shù)據(jù),簡(jiǎn)單示例:

Foo foo = new Foo();
foo.setName("test");
Map<String, Object> context = new HashMap<String, Object>();
context.put("foo",foo);
String expression = "foo.name == 'test'";
try {
 Boolean result = (Boolean) Ognl.getValue(expression,context);
 System.out.println(result);
} catch (OgnlException e) {
 e.printStackTrace();
}

MVEL

MVEL最初作為Mike Brock創(chuàng)建的 Valhalla項(xiàng)目的表達(dá)式計(jì)算器(expression evaluator),相比最初的OGNL、JEXL和JUEL等項(xiàng)目,而它具有遠(yuǎn)超它們的性能、功能和易用性 - 特別是集成方面。它不會(huì)嘗試另一種JVM語言,而是著重解決嵌入式腳本的問題。

MVEL主要使用在Drools,是Drools規(guī)則引擎不可分割的一部分。

MVEL語法較為豐富,不僅包含了基本的屬性表達(dá)式,布爾表達(dá)式,變量復(fù)制和方法調(diào)用,還支持函數(shù)定義,詳情參見MVEL Language Guide。

MVEL在執(zhí)行語言時(shí)主要有解釋模式(Interpreted Mode)和編譯模式(Compiled Mode)兩種:

解釋模式(Interpreted Mode)是一個(gè)無狀態(tài)的,動(dòng)態(tài)解釋執(zhí)行,不需要負(fù)載表達(dá)式就可以執(zhí)行相應(yīng)的腳本。編譯模式(Compiled Mode)需要在緩存中產(chǎn)生一個(gè)完全規(guī)范化表達(dá)式之后再執(zhí)行。

//解釋模式
Foo foo = new Foo();
foo.setName("test");
Map context = new HashMap();
String expression = "foo.name == 'test'";
VariableResolverFactory functionFactory = new MapVariableResolverFactory(context);
context.put("foo",foo);
Boolean result = (Boolean) MVEL.eval(expression,functionFactory);
System.out.println(result);

//編譯模式
Foo foo = new Foo();foo.setName("test");
Map context = new HashMap();
String expression = "foo.name == 'test'";
VariableResolverFactory functionFactory = new MapVariableResolverFactory(context);context.put("foo",foo);
Serializable compileExpression = MVEL.compileExpression(expression);

SpEL

SpEl(Spring表達(dá)式語言)是一個(gè)支持查詢和操作運(yùn)行時(shí)對(duì)象導(dǎo)航圖功能的強(qiáng)大的表達(dá)式語言。 它的語法類似于傳統(tǒng)EL,但提供額外的功能,最出色的就是函數(shù)調(diào)用和簡(jiǎn)單字符串的模板函數(shù)。SpEL類似于Struts2x中使用的OGNL表達(dá)式語言,能在運(yùn)行時(shí)構(gòu)建復(fù)雜表達(dá)式、存取對(duì)象圖屬性、對(duì)象方法調(diào)用等等,并且能與Spring功能完美整合,如能用來配置Bean定義。

SpEL主要提供基本表達(dá)式、類相關(guān)表達(dá)式及集合相關(guān)表達(dá)式等,詳細(xì)參見Spring 表達(dá)式語言 (SpEL)。

類似與OGNL,SpEL具有expression(表達(dá)式),Parser(解析器),EvaluationContext(上下文)等基本概念;類似與MVEL,SpEl也提供了解釋模式和編譯模式兩種運(yùn)行模式。

//解釋器模式
Foo foo = new Foo();
foo.setName("test");
// Turn on:
// - auto null reference initialization
// - auto collection growing
SpelParserConfiguration config = new SpelParserConfiguration(true,true);
ExpressionParser parser = new SpelExpressionParser(config);
String expressionStr = "#foo.name == 'test'";
StandardEvaluationContext context = new StandardEvaluationContext();
context.setVariable("foo",foo);
Expression expression = parser.parseExpression(expressionStr);
Boolean result = expression.getValue(context,Boolean.class);

//編譯模式
config = new SpelParserConfiguration(SpelCompilerMode.IMMEDIATE, RunSpel.class.getClassLoader());
parser = new SpelExpressionParser(config);
context = new StandardEvaluationContext();
context.setVariable("foo",foo);
expression = parser.parseExpression(expressionStr);
result = expression.getValue(context,Boolean.class);

規(guī)則引擎

一些規(guī)則引擎(rule engine):aviatoreasy-rules,drools,esper

aviator

AviatorScript是一門高性能、輕量級(jí)寄宿于 JVM 之上的腳本語言。

使用場(chǎng)景包括:

  • 規(guī)則判斷及規(guī)則引擎
  • 公式計(jì)算
  • 動(dòng)態(tài)腳本控制
  • 集合數(shù)據(jù) ELT 等
public class Test {
 public static void main(String[] args) {
  String expression = "a+(b-c)>100";
  // 編譯表達(dá)式
  Expression compiledExp = AviatorEvaluator.compile(expression);

  Map<String, Object> env = new HashMap<>();
  env.put("a", 100.3);
  env.put("b", 45);
  env.put("c", -199.100);

  // 執(zhí)行表達(dá)式
  Boolean result = (Boolean) compiledExp.execute(env);
  System.out.println(result);
 }
}

easy-rules

Easy Rules is a Java rules engine。

使用POJO定義規(guī)則:

@Rule(name = "weather rule", description = "if it rains then take an umbrella")
public class WeatherRule {

 @Condition
 public boolean itRains(@Fact("rain") boolean rain) {
  return rain;
 }
 
 @Action
 public void takeAnUmbrella() {
  System.out.println("It rains, take an umbrella!");
 }
}

Rule weatherRule = new RuleBuilder()
  .name("weather rule")
  .description("if it rains then take an umbrella")
  .when(facts -> facts.get("rain").equals(true))
  .then(facts -> System.out.println("It rains, take an umbrella!"))
  .build();

支持使用表達(dá)式語言(MVEL/SpEL)來定義規(guī)則:

weather-rule.ymlexample:

name: "weather rule"
description: "if it rains then take an umbrella"
condition: "rain == true"
actions:
 - "System.out.println(\"It rains, take an umbrella!\");"
MVELRuleFactory ruleFactory = new MVELRuleFactory(new YamlRuleDefinitionReader());
Rule weatherRule = ruleFactory.createRule(new FileReader("weather-rule.yml"));

觸發(fā)規(guī)則:

public class Test {
 public static void main(String[] args) {
  // define facts
  Facts facts = new Facts();
  facts.put("rain", true);

  // define rules
  Rule weatherRule = ...
  Rules rules = new Rules();
  rules.register(weatherRule);

  // fire rules on known facts
  RulesEngine rulesEngine = new DefaultRulesEngine();
  rulesEngine.fire(rules, facts);
 }
}

drools

An open source rule engine,DMN engineand complex event processing (CEP) engine for Java and the JVM Platform.

定義規(guī)則:

import com.lrq.wechatDemo.domain.User // 導(dǎo)入類
dialect "mvel"
rule "age" // 規(guī)則名,唯一
 when
  $user : User(age<15 || age>60) //規(guī)則的條件部分
 then
  System.out.println("年齡不符合要求!");
end

參考例子:

public class TestUser {
 private static KieContainer container = null;
 private KieSession statefulKieSession = null;

 @Test
 public void test(){
  KieServices kieServices = KieServices.Factory.get();
  container = kieServices.getKieClasspathContainer();
  statefulKieSession = container.newKieSession("myAgeSession");
  User user = new User("duval yang",12);
  statefulKieSession.insert(user);
  statefulKieSession.fireAllRules();
  statefulKieSession.dispose();
 }
}

esper

Esper is a component for complex event processing (CEP), streaming SQL and event series analysis, available for Java as Esper, and for .NET as NEsper.

一個(gè)例子:

public class Test {
 public static void main(String[] args) throws InterruptedException {
  EPServiceProvider epService = EPServiceProviderManager.getDefaultProvider();
 
  EPAdministrator admin = epService.getEPAdministrator();
 
  String product = Apple.class.getName();
  String epl = "select avg(price) from " + product + ".win:length_batch(3)";
 
  EPStatement state = admin.createEPL(epl);
  state.addListener(new AppleListener());
 
  EPRuntime runtime = epService.getEPRuntime();
 
  Apple apple1 = new Apple();
  apple1.setId(1);
  apple1.setPrice(5);
  runtime.sendEvent(apple1);
 
  Apple apple2 = new Apple();
  apple2.setId(2);
  apple2.setPrice(2);
  runtime.sendEvent(apple2);
 
  Apple apple3 = new Apple();
  apple3.setId(3);
  apple3.setPrice(5);
  runtime.sendEvent(apple3);
 }
}

drools和esper都是比較重的規(guī)則引擎,詳見其官方文檔。

動(dòng)態(tài)JVM語言

Groovy

Groovy除了Gradle上的廣泛應(yīng)用之外,另一個(gè)大范圍的使用應(yīng)該就是結(jié)合Java使用動(dòng)態(tài)代碼了。Groovy的語法與Java非常相似,以至于多數(shù)的Java代碼也是正確的Groovy代碼。Groovy代碼動(dòng)態(tài)的被編譯器轉(zhuǎn)換成Java字節(jié)碼。由于其運(yùn)行在JVM上的特性,Groovy可以使用其他Java語言編寫的庫(kù)。

Groovy可以看作給Java靜態(tài)世界補(bǔ)充動(dòng)態(tài)能力的語言,同時(shí)Groovy已經(jīng)實(shí)現(xiàn)了java不具備的語言特性:

  • 函數(shù)字面值;
  • 對(duì)集合的一等支持;
  • 對(duì)正則表達(dá)式的一等支持;
  • 對(duì)xml的一等支持;

Groovy作為基于JVM的語言,與表達(dá)式語言存在語言級(jí)的不同,因此在語法上比表達(dá)還是語言更靈活。Java在調(diào)用Groovy時(shí),都需要將Groovy代碼編譯成Class文件。

Groovy 可以采用GroovyClassLoader、GroovyShell、GroovyScriptEngine和JSR223等方式與Java語言集成。

一個(gè)使用GroovyClassLoader動(dòng)態(tài)對(duì)json對(duì)象進(jìn)行filter的例子:

public class GroovyFilter implements Filter {
 private static String template = "" +
   "package com.alarm.eagle.filter;" +
   "import com.fasterxml.jackson.databind.node.ObjectNode;" +
   "def match(ObjectNode o){[exp]}";

 private static String method = "match";

 private String filterExp;

 private transient GroovyObject filterObj;

 public GroovyFilter(String filterExp) throws Exception {
  ClassLoader parent = Thread.currentThread().getContextClassLoader();
  GroovyClassLoader classLoader = new GroovyClassLoader(parent);
  Class clazz = classLoader.parseClass(template.replace("[exp]", filterExp));
  filterObj = (GroovyObject)clazz.newInstance();
 }

 public boolean filter(ObjectNode objectNode) {
  return (boolean)filterObj.invokeMethod(method, objectNode);
 }
}

Java每次調(diào)用Groovy代碼都會(huì)將Groovy編譯成Class文件,因此在調(diào)用過程中會(huì)出現(xiàn)JVM級(jí)別的問題。如使用GroovyShell的parse方法導(dǎo)致perm區(qū)爆滿的問題,使用GroovyClassLoader加載機(jī)制導(dǎo)致頻繁gc問題和CodeCache用滿,導(dǎo)致JIT禁用問題等,相關(guān)問題可以參考深入學(xué)習(xí)java中的Groovy 和 Scala 類。

參考:

Java各種規(guī)則引擎:https://www.jianshu.com/p/41ea7a43093c

Java中使用動(dòng)態(tài)代碼:http://brucefengnju.github.io/post/dynamic-code-in-java/

量身定制規(guī)則引擎,適應(yīng)多變業(yè)務(wù)場(chǎng)景:https://my.oschina.net/yygh/blog/616808?p=1

總結(jié)

到此這篇關(guān)于Java中動(dòng)態(tài)規(guī)則的實(shí)現(xiàn)方式的文章就介紹到這了,更多相關(guān)Java動(dòng)態(tài)規(guī)則內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java學(xué)習(xí)之理解自動(dòng)拆裝箱特性

    java學(xué)習(xí)之理解自動(dòng)拆裝箱特性

    這篇文章主要介紹java自動(dòng)拆裝箱特性以及java自動(dòng)拆裝箱的應(yīng)用,有需要的朋友可以借鑒參考下,希望可以有所幫助,祝大家早日升職加薪
    2021-09-09
  • Struts2動(dòng)態(tài)結(jié)果集代碼示例

    Struts2動(dòng)態(tài)結(jié)果集代碼示例

    這篇文章主要介紹了Struts2動(dòng)態(tài)結(jié)果集的有關(guān)內(nèi)容,涉及具體代碼示例,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-09-09
  • Mybatis-plus自定義SQL注入器查詢@TableLogic邏輯刪除后的數(shù)據(jù)詳解

    Mybatis-plus自定義SQL注入器查詢@TableLogic邏輯刪除后的數(shù)據(jù)詳解

    這篇文章主要給大家介紹了關(guān)于Mybatis-plus自定義SQL注入器查詢@TableLogic邏輯刪除后的數(shù)據(jù)的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2023-03-03
  • java構(gòu)建OAuth2授權(quán)服務(wù)器

    java構(gòu)建OAuth2授權(quán)服務(wù)器

    本文主要介紹了java構(gòu)建OAuth2授權(quán)服務(wù)器,文中通過示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-07-07
  • Java中List轉(zhuǎn)Map的幾種具體實(shí)現(xiàn)方式和特點(diǎn)

    Java中List轉(zhuǎn)Map的幾種具體實(shí)現(xiàn)方式和特點(diǎn)

    這篇文章主要介紹了幾種常用的List轉(zhuǎn)Map的方式,包括使用for循環(huán)遍歷、Java8StreamAPI、ApacheCommonsCollections和GoogleGuava,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2025-01-01
  • Java中的MultipartFile接口和File類解讀

    Java中的MultipartFile接口和File類解讀

    本文主要介紹了Java中的File類和Spring框架中的MultipartFile接口,File類提供了對(duì)文件和目錄操作的方法,如創(chuàng)建、刪除、重命名、判斷文件是否存在等,MultipartFile接口用于處理文件上傳,提供了獲取上傳文件信息和保存上傳文件的方法
    2025-02-02
  • 基于Springboot實(shí)現(xiàn)送水公司信息管理系統(tǒng)

    基于Springboot實(shí)現(xiàn)送水公司信息管理系統(tǒng)

    這篇文章主要介紹了基于Springboot實(shí)現(xiàn)送水公司信息管理,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-01-01
  • java 可變參數(shù)詳解及實(shí)例

    java 可變參數(shù)詳解及實(shí)例

    這篇文章主要介紹了java 可變參數(shù)詳解及實(shí)例的相關(guān)資料,需要的朋友可以參考下
    2017-03-03
  • Java實(shí)現(xiàn)計(jì)算器設(shè)計(jì)

    Java實(shí)現(xiàn)計(jì)算器設(shè)計(jì)

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)計(jì)算器設(shè)計(jì),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • Spring boot集成spring session實(shí)現(xiàn)session共享的方法

    Spring boot集成spring session實(shí)現(xiàn)session共享的方法

    這篇文章主要介紹了Spring boot集成spring session實(shí)現(xiàn)session共享的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-06-06

最新評(píng)論

大关县| 福清市| 司法| 陕西省| 洛浦县| 德保县| 霍林郭勒市| 南丰县| 黑龙江省| 常宁市| 东平县| 怀宁县| 库尔勒市| 铁岭市| 云南省| 济南市| 广南县| 澎湖县| 武隆县| 北流市| 鸡泽县| 上犹县| 丰台区| 蓬溪县| 陆河县| 孝昌县| 万盛区| 桓台县| 邛崃市| 民权县| 赤峰市| 墨玉县| 东乡族自治县| 汶上县| 平罗县| 文化| 长兴县| 岳阳县| 六安市| 湘阴县| 中西区|