Drools入門(三)——規(guī)則文件語法

引用

http://www.reibang.com/p/ae9a62588da4

擴(kuò)充

多規(guī)則文件執(zhí)行

多個(gè)drl文件只要package相同則表示它們用的是同一個(gè)KieBaseModel慢逾,此時(shí)獲取該KieBaseModel下的KieSession調(diào)用執(zhí)行規(guī)則引擎時(shí)會(huì)批量!!執(zhí)行該KieBaseModel下的所有規(guī)則

注意:對(duì)于規(guī)則引擎來說不管是同一份文件里面寫多個(gè)規(guī)則還是分開多個(gè)文件寫多個(gè)規(guī)則携丁,最終都是以package作為批量執(zhí)行單位

規(guī)則腳本解析過程

//創(chuàng)建整體規(guī)則引擎建造者
KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem);
kieBuilder.buildAll();
...
//創(chuàng)建規(guī)則項(xiàng)目
KieModuleKieProject kProject = kprojectSupplier.apply( memoryKieModule, classLoader );
buildKieProject( results, kProject, trgMfs );
...
//創(chuàng)建規(guī)則builder
KnowledgeBuilderImpl kbuilder = ( KnowledgeBuilderImpl ) createKnowledgeBuilder( kBaseModel, kModule );
//將規(guī)則文件分配并加載到對(duì)應(yīng)的packageDescr里面沮协,并調(diào)用builder解析每個(gè)package和及其里面的所有規(guī)則
kBuilder.buildPackages(buildPackageDescr());
//根據(jù)packageDescr創(chuàng)建packageRegisty作為最后存儲(chǔ)規(guī)則的地方
PackageRegistry pkgRegistry = getPackageRegistry(packageDescr.getNamespace());
//對(duì)包里面的每條規(guī)則進(jìn)行解析
private void compileRulesLevel(PackageDescr packageDescr, PackageRegistry pkgRegistry, List<RuleDescr> rules) {
    boolean parallelRulesBuild = this.kBase == null && parallelRulesBuildThreshold != -1 && rules.size() > parallelRulesBuildThreshold;
    if (parallelRulesBuild) {
        .....
        .....
    } else {
        for (RuleDescr ruleDescr : rules) {
            if (filterAccepts(ResourceChange.Type.RULE, ruleDescr.getNamespace(), ruleDescr.getName())) {
                //初始化規(guī)則
                initRuleDescr(packageDescr, pkgRegistry, ruleDescr);
                //創(chuàng)建規(guī)則上下文
                RuleBuildContext context = buildRuleBuilderContext(pkgRegistry, ruleDescr);
                //將規(guī)則解析結(jié)果存放起來
                this.results.addAll(addRule(context));
                //將解析后的規(guī)則存放到packageRegistry中
                pkgRegistry.getPackage().addRule(context.getRule());
            }
        }
    }
}

當(dāng)運(yùn)行到上面第10行時(shí)揖膜,在“創(chuàng)建規(guī)則builder”的時(shí)候會(huì)去加載規(guī)則引擎默認(rèn)的配置文件META-INF/kie.properties.confMETA-INF/kie.default.properties.conf绣夺,規(guī)則引擎中只存在META-INF/kie.default.properties.conf授药,非默認(rèn)配置文件是留給使用者的荆秦,如果打算修改里面的配置屬性可以在自己項(xiàng)目中創(chuàng)建一份META-INF/kie.properties.conf背捌,默認(rèn)配置文件內(nèi)容如下

drools.maintainTms = true
drools.shadowproxy = true
drools.shadowproxy.exclude =
drools.sequential = false
drools.sequential.agenda = sequential
drools.removeIdentities = false
drools.shareAlphaNodes = true
drools.shareBetaNodes = true
drools.alphaMemory = false
drools.alphaNodeHashingThreshold = 3
drools.compositeKeyDepth = 3
drools.indexLeftBetaMemory = true
drools.indexRightBetaMemory = true
drools.equalityBehavior = IDENTITY
drools.logicalOverride = DISCARD
drools.conflictResolver = org.drools.core.conflict.DepthConflictResolver
drools.consequenceExceptionHandler = org.drools.core.runtime.rule.impl.DefaultConsequenceExceptionHandler
drools.workDefinitions = WorkDefinitions.conf
droools.lrUnlinkingEnabled = false
drools.declarativeAgendaEnabled = false
drools.permgenThreshold = 90
#默認(rèn)規(guī)則引擎解析器
drools.dialect.default = java
drools.dialect.java = org.drools.compiler.rule.builder.dialect.java.JavaDialectConfiguration
drools.dialect.java.compiler = ECLIPSE

drools.dialect.mvel = org.drools.compiler.rule.builder.dialect.mvel.MVELDialectConfiguration
drools.dialect.mvel.strict = true
drools.dialect.mvel.langLevel = 4
#內(nèi)聯(lián)函數(shù)
drools.accumulate.function.max = org.drools.core.base.accumulators.MaxAccumulateFunction
drools.accumulate.function.maxN = org.drools.core.base.accumulators.NumericMaxAccumulateFunction
drools.accumulate.function.maxI = org.drools.core.base.accumulators.IntegerMaxAccumulateFunction
drools.accumulate.function.maxL = org.drools.core.base.accumulators.LongMaxAccumulateFunction
drools.accumulate.function.min = org.drools.core.base.accumulators.MinAccumulateFunction
drools.accumulate.function.minN = org.drools.core.base.accumulators.NumericMinAccumulateFunction
drools.accumulate.function.minI = org.drools.core.base.accumulators.IntegerMinAccumulateFunction
drools.accumulate.function.minL = org.drools.core.base.accumulators.LongMinAccumulateFunction
drools.accumulate.function.count = org.drools.core.base.accumulators.CountAccumulateFunction
drools.accumulate.function.collectList = org.drools.core.base.accumulators.CollectListAccumulateFunction
drools.accumulate.function.collectSet = org.drools.core.base.accumulators.CollectSetAccumulateFunction
drools.accumulate.function.average = org.drools.core.base.accumulators.AverageAccumulateFunction
drools.accumulate.function.averageBD = org.drools.core.base.accumulators.BigDecimalAverageAccumulateFunction
drools.accumulate.function.sum = org.drools.core.base.accumulators.SumAccumulateFunction
drools.accumulate.function.sumI = org.drools.core.base.accumulators.IntegerSumAccumulateFunction
drools.accumulate.function.sumL = org.drools.core.base.accumulators.LongSumAccumulateFunction
drools.accumulate.function.sumBI = org.drools.core.base.accumulators.BigIntegerSumAccumulateFunction
drools.accumulate.function.sumBD = org.drools.core.base.accumulators.BigDecimalSumAccumulateFunction
drools.accumulate.function.variance = org.drools.core.base.accumulators.VarianceAccumulateFunction
drools.accumulate.function.standardDeviation = org.drools.core.base.accumulators.StandardDeviationAccumulateFunction

drools.evaluator.coincides = org.drools.core.base.evaluators.CoincidesEvaluatorDefinition
drools.evaluator.before = org.drools.core.base.evaluators.BeforeEvaluatorDefinition
drools.evaluator.after = org.drools.core.base.evaluators.AfterEvaluatorDefinition
drools.evaluator.meets = org.drools.core.base.evaluators.MeetsEvaluatorDefinition
drools.evaluator.metby = org.drools.core.base.evaluators.MetByEvaluatorDefinition
drools.evaluator.overlaps = org.drools.core.base.evaluators.OverlapsEvaluatorDefinition
drools.evaluator.overlappedby = org.drools.core.base.evaluators.OverlappedByEvaluatorDefinition
drools.evaluator.during = org.drools.core.base.evaluators.DuringEvaluatorDefinition
drools.evaluator.includes = org.drools.core.base.evaluators.IncludesEvaluatorDefinition
drools.evaluator.starts = org.drools.core.base.evaluators.StartsEvaluatorDefinition
drools.evaluator.startedby = org.drools.core.base.evaluators.StartedByEvaluatorDefinition
drools.evaluator.finishes = org.drools.core.base.evaluators.FinishesEvaluatorDefinition
drools.evaluator.finishedby = org.drools.core.base.evaluators.FinishedByEvaluatorDefinition
drools.evaluator.set = org.drools.core.base.evaluators.SetEvaluatorsDefinition
drools.evaluator.matches = org.drools.core.base.evaluators.MatchesEvaluatorsDefinition
drools.evaluator.soundslike = org.drools.core.base.evaluators.SoundslikeEvaluatorsDefinition

源碼在ChainedProperties.class的構(gòu)造函數(shù)中

private ChainedProperties(String confFileName, ClassLoader classLoader) {
    addProperties( System.getProperties() );

    loadProperties( "META-INF/kie." + confFileName, classLoader, this.props );
    loadProperties( "META-INF/kie.default." + confFileName, classLoader, this.defaultProps);

    // this happens only in OSGi: for some reason doing
    // ClassLoader.getResources() doesn't work but doing
    // Class.getResourse() does
    if (this.defaultProps.isEmpty()) {
        try {
            Class<?> c = Class.forName( "org.drools.core.WorkingMemory", false, classLoader);
            URL confURL = c.getResource("/META-INF/kie.default." + confFileName);
            loadProperties(confURL, this.defaultProps);
        } catch (ClassNotFoundException e) { }
    }
}

配置文件中值得注意的地方是默認(rèn)的編譯器是Eclipse戳粒,首選語言是java路狮,drl文件會(huì)被分為兩部分,一部分是LHS一部分是RHS蔚约,LHS將被解析成一段一段的代碼片段奄妨,RHS會(huì)被解析成java代碼并編譯成class類作為符合條件時(shí)的執(zhí)行結(jié)果

從上面我們大概了解了規(guī)則是如何被加載存放,以及是使用什么編譯工具去編譯drlRHS部分的苹祟,那么這里我們?cè)谏钊胍稽c(diǎn)砸抛,整一份drl文本文件是如何去解析并拆分的呢?接下來將對(duì)這部分進(jìn)行解答树枫,也算是一種拓展吧

回到最初規(guī)則引擎加載的過程中直焙,在調(diào)用buildPackageDescr()創(chuàng)建規(guī)則包時(shí)就進(jìn)行了解析,可以看到是在這一步進(jìn)行的解析拆解砂轻,源碼如下

PackageDescr drlToPackageDescr(Resource resource) throws DroolsParserException,
            IOException {
    PackageDescr pkg;
    boolean hasErrors = false;
    if (resource instanceof DescrResource) {
        pkg = (PackageDescr) ((DescrResource) resource).getDescr();
    } else {
        final DrlParser parser = new DrlParser(configuration.getLanguageLevel());
        pkg = parser.parse(resource);
        this.results.addAll(parser.getErrors());
        if (pkg == null) {
            addBuilderResult(new ParserError(resource, "Parser returned a null Package", 0, 0));
        }
        hasErrors = parser.hasErrors();
    }
    if (pkg != null) {
        pkg.setResource(resource);
    }
    return hasErrors ? null : pkg;
}

繼續(xù)深入源碼可以看到DrlParser在調(diào)用paser(resource)時(shí)創(chuàng)建了DRLLexer箕般,繼續(xù)查看DRLLexer創(chuàng)建過程發(fā)現(xiàn)他創(chuàng)建了ANTLRStringStream,至此找到了最終的答案舔清,drl文件的解析工作使用了第三方工具ANTLR去做的丝里,源碼如下

public static DRLLexer buildLexer(String text, LanguageLevelOption languageLevel) {
    return getDRLLexer(new ANTLRStringStream(text), languageLevel);
}

此時(shí)查看引入的依賴包可以發(fā)現(xiàn)antlr的相關(guān)依賴jar包

antlr依賴

drl文件引入的antlr格式定義文件路徑為src/main/resources/org/drools/compiler/lang/DRL6Lexer.g,由于文件太長(zhǎng)体谒,此處就不貼出來了杯聚,想看的可以直接在項(xiàng)目中搜索該文件

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
禁止轉(zhuǎn)載,如需轉(zhuǎn)載請(qǐng)通過簡(jiǎn)信或評(píng)論聯(lián)系作者抒痒。
  • 序言:七十年代末幌绍,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌傀广,老刑警劉巖颁独,帶你破解...
    沈念sama閱讀 217,185評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異伪冰,居然都是意外死亡誓酒,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門贮聂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來靠柑,“玉大人,你說我怎么就攤上這事吓懈〖弑” “怎么了?”我有些...
    開封第一講書人閱讀 163,524評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵耻警,是天一觀的道長(zhǎng)隔嫡。 經(jīng)常有香客問我,道長(zhǎng)甘穿,這世上最難降的妖魔是什么畔勤? 我笑而不...
    開封第一講書人閱讀 58,339評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮扒磁,結(jié)果婚禮上庆揪,老公的妹妹穿的比我還像新娘。我一直安慰自己妨托,他們只是感情好缸榛,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,387評(píng)論 6 391
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著兰伤,像睡著了一般内颗。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上敦腔,一...
    開封第一講書人閱讀 51,287評(píng)論 1 301
  • 那天均澳,我揣著相機(jī)與錄音,去河邊找鬼符衔。 笑死找前,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的判族。 我是一名探鬼主播躺盛,決...
    沈念sama閱讀 40,130評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼形帮!你這毒婦竟也來了槽惫?” 一聲冷哼從身側(cè)響起周叮,我...
    開封第一講書人閱讀 38,985評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎界斜,沒想到半個(gè)月后仿耽,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,420評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡各薇,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,617評(píng)論 3 334
  • 正文 我和宋清朗相戀三年项贺,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片得糜。...
    茶點(diǎn)故事閱讀 39,779評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖晰洒,靈堂內(nèi)的尸體忽然破棺而出朝抖,到底是詐尸還是另有隱情,我是刑警寧澤谍珊,帶...
    沈念sama閱讀 35,477評(píng)論 5 345
  • 正文 年R本政府宣布治宣,位于F島的核電站,受9級(jí)特大地震影響砌滞,放射性物質(zhì)發(fā)生泄漏侮邀。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,088評(píng)論 3 328
  • 文/蒙蒙 一贝润、第九天 我趴在偏房一處隱蔽的房頂上張望绊茧。 院中可真熱鬧,春花似錦打掘、人聲如沸华畏。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽亡笑。三九已至,卻和暖如春横朋,著一層夾襖步出監(jiān)牢的瞬間仑乌,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評(píng)論 1 269
  • 我被黑心中介騙來泰國打工琴锭, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留晰甚,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,876評(píng)論 2 370
  • 正文 我出身青樓决帖,卻偏偏與公主長(zhǎng)得像压汪,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子古瓤,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,700評(píng)論 2 354