Drools业务逻辑框架

Ruoyi框架前后端交互的整个流程 前提 Jdk、maven等环境部署成功,部署若依项目到本地 第一部分 前端 1、当前网页对应的网址是localhost/system/role对应哪个页面 1.1、前端路由是动态的,url来自于数据库; 1.2、前端文件夹名称以及文件名称、位置与数据库里一一对应 1.3、路由动态赋值 例如: 如果地址是/system/role 就找一个system文件夹下面有role文件夹的文件 2、点击某个页面,上面的数据是... 阅读详情

大部分 web 以及企业级 Java 应用可被分成三部分:与用户交互的前台,与数据库这样的后台系统交互的服务层,以及它们之间的业务逻辑。最近这段时间,通常我们会使用框架来实现前台和后台的需求(例如:Struts, Cocoon, Spring, Hibernate, JDO, 以及实体 Beans),但是却没有一种标准手段很好的组织业务逻辑。像 EJB 和 Spring 这样的框架都以 high level 方式处理,这无助于组织我们的代码。除非我们改变这种凌乱,否则系统将不会健壮,框架中杂乱的 if...then 语句能带给我们可配置性、可读性的优点,以及在其他地方复用代码的愉悦吗?本文将介绍如何使用 Drools 规则引擎框架来解决这些问题。
   
    下列的范例代码展示了我们正要试图努力避免的问题。展示了包含一些业务逻辑的 Java 典型应用。

if  ((user.isMemberOf(AdministratorGroup)
      
&&  user.isMemberOf(teleworkerGroup))
     
||  user.isSuperUser(){
         
         
//  more checks for specific cases
          if ((expenseRequest.code().equals( " B203 " )
           
|| (expenseRequest.code().equals( " A903 " )
                        
&& (totalExpenses < 200 )
                
&& (bossSignOff >  totalExpenses))
           
&& (deptBudget.notExceeded)) {
               
// issue payments
           }  else   if  {
               
// check lots of other conditions
           }
} 
else  {
     
//  even more business logic
}

    我们经常写出类似的(甚至更复杂)业务逻辑。当这些用 Java 实现的业务逻辑成为标准方式时,将存在下列问题:
   
        业务用户怎样在这些难以理解的代码基础上添加另一个条件(比如"C987")?一旦最初开发这些程序的员工离开了,你想成为维护这些代码的人吗?
        我们怎样检查规则的正确性?对业务伙伴的技术人员来说都够复杂的了,更不要说检查。我们可以有系统的测试这些业务逻辑吗?
        很用应用都有相似的业务规则--当其中的一个规则改变,我们能保证这一改变可贯穿整个系统?当新应用使用这些规则,该应用已经部分添加了新的规则,但不完全,我们要把逻辑重写过吗?
        我们经常需要对每个细小调整所带来的改变进行重编译/重部署,而不是坚实的依靠 Java 代码,业务逻辑是否易于配置?
        可否复用已存在的用其他(脚本)语言编写的业务规则逻辑?
       
    J2EE/EJB 以及“IoC inversion of control”框架(比如 Spring,Pico,以及 Avalon)给我们带来的是 high level 代码组织能力。在提供良好复用性、可配置性、以及安全性的同时,没有一个能替代(解决)以上的“spaghetti 代码”范例出现的问题。理想地,无论选择何种框架,不仅仅适合 J2EE 应用,而且也可用于“normal”Java(J2SE)程序,以及大部分普遍采用的表现层以及持久层框架。这种理想框架应该允许我们这样做:
   
        业务用户应该可以方便的阅读和校验业务逻辑。
        业务规则应该可被复用,并可以通过程序进行配置。
        这种框架应该是可升级的,并在高负载情况下运行。
        Java 程序员可以像使用现有的前台(Struts,Spring)和后台(ORM object-relational mapping)框架一样方便地使用这个框架。
       
    另外的问题是,有许多的 web 页面、数据库访问组织方式,业务逻辑在这两种应用中应趋于不同。而框架应该能应付这些并促进代码复用。理想的框架将能“frameworks all the way down.”,通过这种方式使用框架,我们能在应用中大量的“out of the box”,这样我们只为客户记录添加值的部分。
   
规则引擎前来救援

    我们怎样解决问题呢?一种方案是通过规则引擎获取 traction。规则引擎是为组织业务逻辑应运而生的框架,它让开发者专注于做被认为正确的事情上,而不是以 low-level 方式作出决定。
   
    通常,业务用户舒适的表达他们知道的正确的事,而不是 if...else 格式的表达方式。你也许能从业务专家听见这些东西:
   
    “FORM 10A 用来索取额外 200 欧元费用。(FORM 10A is used for expense claims over 200 Euro.)”
    “我们只进行数量在 10,000 以上的贸易。”
    “购买大于 €10m 的要经过公司董事批准。”
   
    通过专注于我们认为正确的事情上,而不是只知道怎样用 Java 代码表达,那么上面的叙述将比之前的代码范例更清晰。我们仍然需要一种机制为我们知道和做决定的事实应用这些规则。这种机制就是规则引擎。
   
Java 中的规则引擎
   
    JSR 94,如同 JBDC 允许我们与多种数据库交互一样,javax.rules 是一组与规则引擎交互的通用标准 API。为什么 JSR-94 没有详细说明实际的规则怎样书写,有下面大量的 Java 规则引擎可供选择:
   
    Jess 或许是最成熟的 Java 规则引擎,有良好的工具支持(包括 Eclipse 插件)以及文档。但是,它是商业软件,而且用 Prolog-style 符号书写规则,对 Java 程序员来说是很晦涩的。
    Jena 是一套开源框架,最初由惠普发起。虽然它有规则引擎以及在 Web 语义方面特别强大,但它并不与 JSR-94 兼容。
    Drools 是与 JSR-94 兼容的规则引擎,并且在 Apache-style 许可下完全开源。它不仅用熟悉的 Java 和 XML 语法表述规则,而且它还有强大的用户、开发者社区。在本文中有范例,我们将使用 Drools,因为它有最容易使用的类似 Java 的语法以及完全开发许可。
   
利用 Drools 开始 Java 开发

    假设有这样的场景:在阅读本文的数分钟后,你老板要求你做一个股票交易应用原型。这时,业务用户尚未被完全定义业务逻辑,你马上会想到最好的办法是用规则引擎实现。最终系统将可通过内部网访问,而且还要和后台数据库以及消息系统通讯。在着手行动前,先下载 Drools 框架(与支持库一起)。在你喜欢的 IDE 中创建新项目,确定所有 .jar 文件被引用进项目,如图 1 中所示。截图是基于 Eclipse 的,不过在其他 IDE 中创建也是相似的。

      Libraries needed to Run Drools
                   图 1. 运行 Drools 所需要的库
   
    如果我们的股票交易系统很混乱,将失去大量潜在客户(商机),所以在系统的整个步骤中放入一些模拟器(simulator)是至关重要的。这种模拟器给了你决心采用该系统的信心,甚至规则改变以后所带来的麻烦。我们将借助敏捷工具箱中的工具,以及 JUnit(http://www.junit.org/) 框架进行模拟。
   
    如下,我们写的第一段代码是 JUnit 测试/模拟器。即使我们无法测试每个对应用有价值的输入组合,但有测试也比没有测试的好。在这个范例中,所有的文件和类(包括单元测试)都放入一个文件夹/包中,但实际上,你可能会用一种适当的包、文件夹结构。范例代码中我们用 Log4j 代替 System.out 调用。

import  junit.framework.TestCase;
/*
 * JUnit test for the business rules in the 
 * application.
 * 
 * This also acts a 'simulator' for the business 
 * rules - allowing us to specify the inputs,
 * examine the outputs and see if they match our 
 * expectations before letting the code loose in  
 * the real world.
 
*/
public   class  BusinessRuleTest  extends  TestCase {
  
/**
  * Tests the purchase of a stock
  
*/
  
public   void  testStockBuy()  throws  Exception{
                
    
// Create a Stock with simulated values
    StockOffer testOffer  =   new  StockOffer();
    testOffer.setStockName(
" MEGACORP " );
    testOffer.setStockPrice(
22 );
    testOffer.setStockQuantity(
1000 );
                
    
// Run the rules on it
    BusinessLayer.evaluateStockPurchase(testOffer);
                
    
// Is it what we expected?
    assertTrue(
      testOffer.getRecommendPurchase()
!= null );
    
    assertTrue(
" YES " .equals(
      testOffer.getRecommendPurchase()));               
   }
}

    这是最基本的 JUnt 测试,我们知道我们的系统应该买所有低于 100 欧元的股票。很明显,要是没有数据持有类(StockOffer.java)和业务层类(BusinessLayer.java)它将无法编译。这两个类如下。

/**
 * Facade for the Business Logic in our example.
 * 
 * In this simple example, all our business logic
 * is contained in this class but in reality it 
 * would delegate to other classes as required.
*/
public   class  BusinessLayer {
  
/**
   * Evaluate whether or not it is a good idea
   * to purchase this stock.
   * 
@param  stockToBuy
   * 
@return  true if the recommendation is to buy 
   *   the stock, false if otherwise
   
*/
  
public   static   void  evaluateStockPurchase
    (StockOffer stockToBuy){
                
return   false ;
  }
}

    StockOffer 是这样:

/**
 * Simple JavaBean to hold StockOffer values.
 * A 'Stock offer' is an offer (from somebody else)
 * to sell us a Stock (or Company share).
 
*/
public   class  StockOffer {
        
  
// constants
   public   final   static  String YES = " YES " ;
  
public   final   static  String NO = " NO " ;
        
  
// Internal Variables
   private  String stockName  = null ;
  
private   int  stockPrice = 0 ;
  
private   int  stockQuantity = 0 ;
  
private  String recommendPurchase  =   null ;
        
  
/**
   * 
@return  Returns the stockName.
   
*/
  
public  String getStockName() {
        
return  stockName;
  }
  
/**
   * 
@param  stockName The stockName to set.
   
*/
  
public   void  setStockName(String stockName) {
        
this .stockName  =  stockName;
  }
  
/**
   * 
@return  Returns the stockPrice.
   
*/
  
public   int  getStockPrice() {
        
return  stockPrice;
  }
  
/**
   * 
@param  stockPrice The stockPrice to set.
   
*/
  
public   void  setStockPrice( int  stockPrice) {
        
this .stockPrice  =  stockPrice;
  }
  
/**
   * 
@return  Returns the stockQuantity.
   
*/
  
public   int  getStockQuantity() {
        
return  stockQuantity;
  }
  
/**
   * 
@param  stockQuantity to set.
   
*/
  
public   void  setStockQuantity( int  stockQuantity){
        
this .stockQuantity  =  stockQuantity;
  }
  
/**
   * 
@return  Returns the recommendPurchase.
   
*/
  
public  String getRecommendPurchase() {
        
return  recommendPurchase;
  }
}

    通过 IDE 的 JUnit 插件运行 BusinessRuleTest。如果你不熟悉 JUnit,可在 JUnit 网站找到更多信息。不必惊讶,如图 2 所示第二个断言测试失败,这是因为还没把业务逻辑放在适当的地方。测试结果用高亮显示了模拟器/单元测试所出现的问题,这是很保险的。

  JUnit Test Results
              图 2. JUnit 测试结果
             
用规则编写业务逻辑
   
    在这里,我们要写一些业务逻辑,来表达“一旦股票价格低于 100 欧元,就马上购买。” 要达到这个目的,需调整 BusinessLayer.java:

import  java.io.IOException;
import  org.drools.DroolsException;
import  org.drools.RuleBase;
import  org.drools.WorkingMemory;
import  org.drools.event.DebugWorkingMemoryEventListener;
import  org.drools.io.RuleBaseLoader;
import  org.xml.sax.SAXException;
/**
 * Facade for the Business Logic in our example.
 * 
 * In this simple example, all our business logic
 * is contained in this class but in reality it 
 * would delegate to other classes as required.
 * 
@author  default
 
*/
public   class  BusinessLayer {
  
// Name of the file containing the rules
   private   static   final  String BUSINESS_RULE_FILE =
                              
" BusinessRules.drl " ;
        
  
// Internal handle to rule base
   private   static  RuleBase businessRules  =   null ;
  
/**
   * Load the business rules if we have not 
   * already done so.
   * 
@throws  Exception - normally we try to 
   *          recover from these
   
*/
  
private   static   void  loadRules()
                       
throws  Exception{
    
if  (businessRules == null ){
      businessRules 
=  RuleBaseLoader.loadFromUrl(
          BusinessLayer.
class .getResource(
          BUSINESS_RULE_FILE ) );
    }
  }     
        
  
/**
   * Evaluate whether or not to purchase stock.
   * 
@param  stockToBuy
   * 
@return  true if the recommendation is to buy
   * 
@throws  Exception
   
*/
  
public   static   void  evaluateStockPurchase
       (StockOffer stockToBuy) 
throws  Exception{
                
    
// Ensure that the business rules are loaded
    loadRules();
    
// Some logging of what is going on
    System.out.println(  " FIRE RULES "  );
    System.out.println( 
" ---------- "  );
        
    
// Clear any state from previous runs 
    WorkingMemory workingMemory 
            
=  businessRules.newWorkingMemory();
    
// Small ruleset, OK to add a debug listener 
    workingMemory.addEventListener(
      
new  DebugWorkingMemoryEventListener());
        
    
// Let the rule engine know about the facts
    workingMemory.assertObject(stockToBuy);
        
    
// Let the rule engine do its stuff!!
    workingMemory.fireAllRules();
  }
}

    这个类有些重要方法:
   
    loadRules(),从 BusinessRules.drl 文件加载规则。
    更新后的 evaluateStockPurchase(),用于评估业务规则。这个方法的注解如下:
        可以反复复用相同的 RuleSet(内存中的业务规则是无状态的)。
        为每次评估构造新的 WorkingMemory,因为我们的知识知道这个时刻是正确的。使用 assertObject() 放置已知事实(作为 Java 对象)到内存中。
        Drools 有个事件监听模式,允许我们“查看”事件模型中到底发生了什么。在这里我们用它打印 debug 信息。
        working memory 类中的 fireAllRules() 方法评估和更新规则(在本例中是股票出价)。
   
    再次运行该范例前,需要创建我们的 BusinessRules.drl 文件:

<? xml version="1.0" ?>
< rule-set  name ="BusinessRulesSample"
  xmlns
="http://drools.org/rules"
  xmlns:java
="http://drools.org/semantics/java"
  xmlns:xs
    
="http://www.w3.org/2001/XMLSchema-instance"
  xs:schemaLocation
    
="http://drools.org/rules rules.xsd
  http://drools.org/semantics/java java.xsd"
>
  
<!--  Import the Java Objects that we refer 
                          to in our rules 
-->         
  
< java:import >
    java.lang.Object
  
</ java:import >
  
< java:import >
    java.lang.String
  
</ java:import >
  
< java:import >
    net.firstpartners.rp.StockOffer
  
</ java:import >
  
<!--  A Java (Utility) function we reference 
    in our rules
-->   
  
< java:functions >
    public void printStock(
      net.firstpartners.rp.StockOffer stock)
        {
        System.out.println("Name:"
          +stock.getStockName()
          +" Price: "+stock.getStockPrice()     
          +" BUY:"
          +stock.getRecommendPurchase());
        }
  
</ java:functions >
< rule-set >
  
<!--  Ensure stock price is not too high -->       
  
< rule  name ="Stock Price Low Enough" >
    
<!--  Params to pass to business rule  -->
    
< parameter  identifier ="stockOffer" >
      
< class > StockOffer </ class >
    
</ parameter >
    
<!--  Conditions or 'Left Hand Side' 
        (LHS) that must be met for 
         business rule to fire 
-->
    
<!--  note markup  -->
    
< java:condition >
      stockOffer.getRecommendPurchase() == null
    
</ java:condition >
    
< java:condition >
      stockOffer.getStockPrice() 
<  100
    
</java:condition >
    
<!--  What happens when the business 
                      rule is activated 
-->
    
< java:consequence >
        stockOffer.setRecommendPurchase(
                              StockOffer.YES);  
          printStock(stockOffer);
    
</ java:consequence >
  
</ rule >
</ rule-set >

    该规则文件有些有趣部分:
   
        只有在 XML-Schema 定义 Java 对象之后,我们才能引用进规则。这些对象可以是来自于任何必须的 Java 类库。
        接下来是 functions,它们可以与标准 Java 代码进行混合。既然这样,我们干脆混入些日志功能来帮助我们观察发生了什么。
        再下来是我们的 rule set,rule set 由一到多个规则组成。
        每个规则可持有参数(StockOffer 类),并需要实现一个或多个条件,当条件符合时,将会执行相应结果。
       
    在修改和编译完代码后,再次运行 JUnit 测试。这次调用了业务规则,我们的逻辑进行正确地评估,并且测试通过,参看图 3。恭喜--你已经构建了第一个基于规则的应用!

    Successful JUnit Test
    图 3.成功的 JUnit 测试
   
使规则更聪明

    刚刚构建好应用,你就向业务用户示范上面的原型,他们却忽然想起先前并没有提出的规则。其中一个新规则是当数量是负数时(<0)不能进行股票交易。“没关系,”你说,接着回到办公桌上,紧扣已有知识,快速演化你的系统。
   
    首先要更新模拟器,把以下代码添加到 BusinessRuleTest.java:

   /**
   * Tests the purchase of a stock 
   * makes sure the system will not accept 
   * negative numbers.
   
*/
  
public   void  testNegativeStockBuy() 
                                
throws  Exception{
                
    
// Create a Stock with our simulated values
      StockOffer testOffer  =   new  StockOffer();
        testOffer.setStockName(
" MEGACORP " );
        testOffer.setStockPrice(
- 22 );
        testOffer.setStockQuantity(
1000 );
                
        
// Run the rules on it
        BusinessLayer
              .evaluateStockPurchase(testOffer);
                
        
// Is it what we expected?
        assertTrue( " NO " .equals(
          testOffer.getRecommendPurchase()));
}

    这个测试是为业务用户描述的新规则建立的。正如意料之中的,如果运行 JUnit 测试,我们的新测试将失败。所以,我们要添加新的规则到 .drl 文件:

<!--  Ensure that negative prices 
                            are not accepted
-->       
  
< rule  name ="Stock Price Not Negative" >
    
<!--  Parameters we can pass into 
                          the business rule 
-->
    
< parameter  identifier ="stockOffer" >
      
< class > StockOffer </ class >
    
</ parameter >
    
<!--  Conditions or 'Left Hand Side' (LHS) 
       that must be met for rule to fire 
-->
    
< java:condition >
      stockOffer.getStockPrice() 
<  0
    
</java:condition >
    
<!--  What happens when the business rule 
                              is activated 
-->
    
< java:consequence >
      stockOffer.setRecommendPurchase(
                                  StockOffer.NO);       
      printStock(stockOffer);
    
</ java:consequence >
  
</ rule >

    这个规则的格式和前面的相似,除了 (用于测试负数)以及 用于设置推荐购买为 No 以外。我们再次运行测试,这次通过了。
   
    这时,如果你习惯于过程化编程(像大多数 Java 程序员一样),你也许要搔头皮了:在一个文件中包含两个独立的业务规则,而且我们也没告诉规则引擎哪个更重要。不管怎样,股票价格(对于 -22)都满足两个规则(也就是少于 0 和少于 100)。尽管这样,我们仍能得到正确结果,即使交换规则顺序。这是怎么做到的呢?
   
    下面的控制台输出有助于我们了解到底怎么回事。我们看见两个规则都执行了([activationfired] 这行),Recommend Buy 第一次被设置为 Yes 接着又被设置成 No。Drools 怎么知道执行这些规则的正确顺序呢?如果你观察 Stock Price Low Enough 规则,将发现 recommendPurchase() 其中一个条件为空。通过这点,Drools 规则引擎足以判断 Stock Price Low Enough 规则应该在 Stock Price Not Negative 规则之前执行。这个过程称为 conflict resolution。

FIRE RULES
----------
[ConditionTested: rule=Stock Price Not Negative;
  condition=[Condition: stockOffer.getStockPrice()
  < 0]; passed=true; tuple={[]}]
[ActivationCreated: rule=Stock Price Not Negative;
  tuple={[]}]
[ObjectAsserted: handle=[fid:2];
  
object=net.firstpartners.rp.StockOffer@16546ef]
[ActivationFired: rule=Stock Price Low Enough;
   tuple={[]}]
[ActivationFired: rule=Stock Price Not Negative;
   tuple={[]}]
Name:MEGACORP Price: -22 BUY:YES
Name:MEGACORP Price: -22 BUY:NO


    如果你是一名过程化程序员,无论你用怎样聪明的方式考虑这些,你都不会完全相信。这就是为什么要进行单元/模拟器测试的原因:进行 "坚固的" JUnit 测试(使用一般 Java 代码)确保规则引擎所作出的决定是按照我们所想要的路线进行。(不会花费大量金钱在无价值的股票上)同时,规则引擎的强大和伸缩性允许我们快速开发业务逻辑。
   
    稍后,我们将学习如何用更加精练的解决方案进行冲突处理。
   
冲突结局方案

    现在业务伙伴被打动了,并且开始考虑进行选择了。随即他们遇到了个 XYZ 公司股票的问题,那么我们来实现新规则吧:只有 XYZ 公司股票低于 10 欧元才可购买。
   
    像以前一样,添加测试到模拟器,接着在规则文件中包含新业务规则。首先在 BusinessRuleTest.java 中添加新方法:

  /**
 * Makes sure the system will buy stocks 
 * of XYZ corp only if it really cheap
 
*/
public   void  testXYZStockBuy()  throws  Exception{
        
  
// Create a Stock with our simulated values
  StockOffer testOfferLow  =   new  StockOffer();
  StockOffer testOfferHigh 
=   new  StockOffer();
                
  testOfferLow.setStockName(
" XYZ " );
  testOfferLow.setStockPrice(
9 );
  testOfferLow.setStockQuantity(
1000 );
                
  testOfferHigh.setStockName(
" XYZ " );
  testOfferHigh.setStockPrice(
11 );
  testOfferHigh.setStockQuantity(
1000 );
                
  
// Run the rules on it and test
  BusinessLayer.evaluateStockPurchase(
    testOfferLow);
  assertTrue(
" YES " .equals(
    testOfferLow.getRecommendPurchase()));
                
  BusinessLayer.evaluateStockPurchase(
    testOfferHigh);
  assertTrue(
" NO " .equals(
    testOfferHigh.getRecommendPurchase()));             
}

    接下来向 BusinessRules.drl 中添加新 :

   < rule  name ="XYZCorp"  salience ="-1" >
   
<!--  Parameters we pass to rule  -->
   
< parameter  identifier ="stockOffer" >
     
< class > StockOffer </ class >
   
</ parameter >
    
   
< java:condition >
     stockOffer.getStockName().equals("XYZ")
   
</ java:condition >  
   
< java:condition >
     stockOffer.getRecommendPurchase() == null
   
</ java:condition >
   
< java:condition >
     stockOffer.getStockPrice() > 10
   
</ java:condition >
        
   
<!--  What happens when the business 
                                rule is activated 
-->
   
< java:consequence >  
     stockOffer.setRecommendPurchase(
       StockOffer.NO);  
     printStock(stockOffer);
   
</ java:consequence >
  
</ rule >

    注意业务规则文件,在 rule name 后面,我们把 salience 设置成 -1(到目前为止了解的最低优先级)。大多数规则在系统中是冲突的,这意味着 Drools 必须为规则的执行顺序做判断,假设这些条件都与规则匹配。默认的判断方式是:
       
    Salience:赋予的值。
    Recency:使用规则的次数。
    Complexity:首先执行有复杂值的特定规则。
    LoadOrder:规则载入的顺序。
   
    如果没有显示的在规则中详细指明,将会发生:
   
    XYZ 公司规则("当价格高于 10 欧元就不购买 XYZ 的股票")将先执行(Recommend Buy 标志被设置为 No)。
    接着更多的一般规则("购买所有 100 欧元以下的股票")被执行,把 Recommend Buy 标志设置为 yes。
   
    这会给我们一个不想要的结果。然而,一旦在范例中设置了 saliency 要素,最终的测试和业务规则将像预期的那样顺利运行。
   
    大多数时间,编写清晰的规则和设置 saliency 将给 Drools 足够信息以选择合适的顺序执行规则,有时我们想改变整个规则冲突处理方式。下面的例子说明了如何改变,告诉规则引擎首先执行最简单的规则。要注意的是:改变冲突解决方案要小心,它可能从根本上改变规则引擎的行为。

   // Generate our list of conflict resolvers
  ConflictResolver[] conflictResolvers  =  
    
new  ConflictResolver[] {
      SalienceConflictResolver.getInstance(),
      RecencyConflictResolver.getInstance(),
        SimplicityConflictResolver.getInstance(),
        LoadOrderConflictResolver.getInstance()
    };
                
  
// Wrap this up into one composite resolver
  CompositeConflictResolver resolver  =  
    
new  CompositeConflictResolver(
      conflictResolvers);
                        
  
// Specify this resolver when we load the rules
  businessRules  =  RuleBaseLoader.loadFromUrl(
    BusinessLayer.
class .getResource( 
      BUSINESS_RULE_FILE),resolver);

    我们的简单应用由 JUnit 测试驱动,我们不必改变 Drools 处理规则冲突的方式。知道冲突解决方案怎样运作是很有用的,尤其当你的应用为了迎合更复杂、更苛刻的需求时。
   
结束
   
    本文示范了大部分程序员不得不面对的问题:怎样安排复杂业务逻辑的顺序。我们示范了一个使用 Drools 作为解决方案并引入基于规则编程概念的简单应用,包括了怎样在运行时处理规则。接着,后续文章使用这些技术并展示了怎样在企业级 Java 应用中使用。

Drools与SpringBoot集成实践教程 Drools是一个基于Java语言开发的高级业务规则引擎,它的历史可以追溯到2000年代初。经过多年的迭代,Drools已经成为企业级规则引擎领域的佼佼者,被广泛应用于金融、电信、医疗等领域,极大地提高了业务的灵活性和响应速度。SpringBoot提供了一种新的编程模式,通过自动配置机制极大地简化了基于Spring的应用程序的配置和部署。它利用了约定优于配置(convention over configuration)的原则,能根据项目依赖自动配置Spring和第三方库。 阅读详情

相关推荐

Drools规则引擎与Spring框架整合实战详解

某些场景下规则需从数据库、Git仓库或配置中心动态加载。可通过自定义Resource实现远程读取:@Override@Override// 省略其他抽象方法...然后注册到该机制支持云原生环境下规则即配置(Rule-as-Config)的架构理念。在现代企业级应用中,业务逻辑的复杂性日益增长,传统硬编码方式难以应对频繁变更的需求。Drools作为一款成熟的规则引擎,通过将“做什么”(业务规则)与“怎么做”(流程控制)分离,实现了高度解耦和可维护性。

weixin_35414484的博客 898

Drools 为你的业务逻辑提供框架[修订]

大部分 web 以及企业级 Java 应用可被分成三部分:与用户交互的前台,与数据库这样的后台系统交互的服务层,以及它们之间的业务逻辑。最近这段时间,通常我们会使用框架来实现前台和后台的需求(例如:Struts, Cocoon, Spring, Hibernate, JDO, 以及实体 Beans),但是却没有一种标准手段很好的组织业务逻辑。像 EJB 和 Spring 这样的框架都以 high ...

srj290310202的专栏 316

CANdelaStudio实战:如何用19服务快速编辑DTC快照数据(附Excel模板)

本文详细介绍了在CANdelaStudio中利用19服务高效编辑DTC快照数据的进阶技巧。通过导出DTC池至Excel进行批量编辑,结合‘Copy from DTC Pool’功能实现配置复用,并分享了构建自定义Excel模板与字段映射的实用方法,帮助工程师将繁琐的手动配置转化为工程化的批量处理,大幅提升诊断数据库开发效率。

weixin_29230773的博客 190

在你的企业级java应用中使用Drools

一花一世界,一叶一菩提 一 前言      最早对Drools感兴趣,是起源于规则引擎.当时是希望能找一个开源工具来做一些规则的处理.      在官方网站上翻了半天资料,却发现Drools一直在强调它不只是一个简单的规则引擎,而是更多的引入工作流的概念.      之后最大的感触就是Drools牵涉到的东西比较多,甚至有一种依照Drools可以创造整个世界的感觉--

dac55300424的专栏 4331

Visual Studio Git 使用指南

Visual Studio 2022深度集成了Git功能,提供了直观的图形界面管理源代码。本文详细介绍了VS中Git的使用方法:从环境准备、克隆/创建仓库开始,重点讲解了"Git更改"窗口的日常操作,包括查看修改、暂存文件、提交推送等。同时涵盖了分支管理、查看历史、解决冲突等核心功能,以及储藏、重置等高级操作。文章还提供了实用技巧,如提交规范、频繁提交等最佳实践。VS的Git集成覆盖了日常开发需求,图形界面与命令行可互补使用,适合各层次开发者高效管理代码版本。

guigenyi的专栏 1565

Oracle EBS R12 AP模块发票导入接口实战:从SQL插入到API调用的完整流程

本文详细解析了Oracle EBS R12 AP模块发票导入接口的完整流程,从SQL插入到API调用的实战技巧。涵盖接口表设计、数据验证、双通道导入机制及错误诊断,特别分享官方文档未提及的高阶优化方案,助力企业实现财务数字化转型。

weixin_33728268的博客 475

21、关于Drools Web版本与java实现简单交互

如何安装kie-drools-wb 请参考workbench安装首先,在kie-drools-wb的客户端创建一个项目,实际上就是一个目录用来存放事实(fact)和规则文件(drl)而已,只是官方这样称呼而已。接着就是编写事实文件(fact)和规则文件(drl),可以在eclipse中编辑好,然后复制过来也行,这里要注意一点,事实文件(fact)与规则文件(drl)尽量名称保持一致,避免不必要的麻...

u013115157的博客 1万+

单片机通信总述——理论部分(CAN、串口、SPI、I2C等)

并行通信:传输原理:数据各个位同时传输;优点:速度快; 缺点:占用引脚资源多。是指使用 8、16、32 及 64 根或更多的数据线(有多少信号为就需要多少信号位)进行传输的通讯方式,可以同一时刻传输多个数据位的数据。串行通信: 传输原理:数据按位顺序传输;优点:占用引脚资源少; 缺点:速度相对较慢。是指设备之间通过一根数据信号线,地线以及控制信号线,按数据位形式一位一位地传输数据的通讯方式,同一时刻只能传输一位(bit)数据。 单工: 数据传输只支持数据在一个方向上传输。信息只能单方向传输的工作方式,一

qq_42475191的博客 1万+

Drools 为你的业务逻辑提供框架(转载)

  大部分 web 以及企业级 Java 应用可被分成三部分:与用户交互的前台,与数据库这样的后台系统交互的服务层,以及它们之间的业务逻辑。最近这段时间,通常我们会使用框架来实现前台和后台的需求(例如:Struts, Cocoon, Spring, Hibernate, JDO, 以及实体 Beans),但是却没有一种标准手段很好的组织业务逻辑。像 EJB 和 Spring 这样的框架都以 hig

joeyshi的专栏 1986

【VeriStand】从零构建HIL测试平台:核心概念、硬件选型与实战配置指南

本文详细介绍了如何从零构建HIL测试平台,涵盖核心概念、硬件选型与实战配置指南。重点解析了VeriStand生态系统的优势,包括开箱即用特性、与LabVIEW的黄金搭档配合及Python支持。通过实战案例和硬件选型建议,帮助工程师高效搭建可靠的HIL测试平台,提升测试效率与安全性。

weixin_29250573的博客 329

Tushare Day2——了解stock_basic数据并根据行业和地区进行统计

了解stock_basic数据 1  stock_basic基础信息2  导入包和stock_basic数据、查看基本信息3  根据行业列进行统计3.1  1.先把不同行业列举出来,看一下一共有多少种行业3.2  2.统计每个行业分别有多少家公司3.3  3.把行业从array的二维数组形式变成list形式3.4  4.把行业从list形式转换成文本形式3.5&nbsp

绒绒的Routine 2796

Drools 为你的业务逻辑提供框架(翻译)

大部分 web 以及企业级 Java 应用可被分成三部分:与用户交互的前台,与数据库这样的后台系统交互的服务层,以及它们之间的业务逻辑。最近这段时间,通常我们会使用框架来实现前台和后台的需求(例如:Struts, Cocoon, Spring, Hibernate, JDO, 以及实体 Beans),但是却没有一种标准手段很好的组织业务逻辑。像 EJB 和 Spring 这样的框架

从前有座山 2155

华为OD机试2025A卷 - BOSS的收入(Java & Python& JS & C++ & C )

华为OD机试2025A卷 - BOSS的收入(Jav一个XX产品行销总公司,只有一个boss,其有若干一级分销,一级分销又有若干二级分销,每个分销只有唯一的上级分销。规定,每个月,下级分销需要将自己的总收入(自己的+下级上交的)每满100元上交15元给自己的上级。现给出一组分销的关系,和每个分销的收入,请找出boss并计算出这个boss的收入。输入:分销关系和收入:[[分销id 上级分销id 收入], [分销id 上级分销id 收入], [分销id 上级分销id 收入]]输出:[boss的ID, 总收入]

算法大师! 1171

业务逻辑外挂--规则引擎概述

通过在POJO上添加注释,以声明的方式定义通过RuleBuilder API,以编程方式定义更多案例可以到这看 https://github.com/j-easy/easy-rules/tree/master/easy-rules-tutorials规则引擎最佳实践面向业务人员或需求人员规则引擎不是银弹,只有在规则变化频繁及业务逻辑多且边界清晰时才使用多一层中间件,多一层分险,特指将规则引擎独立为中间件的方案。

qq_28722667的博客 1538

高通平台WIFI学习-- 基于6GHZ Discovery (STA Scanning)讲解

本文介绍了6GHz频段的网络扫描优化方案。主要内容包括:1)带内发现机制,将6GHz信道分为优先扫描信道(PSC)和非PSC信道,规范了STA发送探测请求的条件及等待时间;2)带外发现机制,通过RNR信息元素实现跨频段AP发现,减少6GHz频段干扰;3)具体扫描流程示例,包括DBS扫描和敏捷扫描的顺序安排。方案通过优化探测请求发送规则和跨频段信息共享,有效降低了信道污染和扫描延迟,日志数据验证了6GHz信道扫描的具体实现过程。

专业开发者的博客,一个从事Android WiFi和蓝牙的工程师 267

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

java 规则引擎 drools框架

1.  drools是什么? drools是一个基于java语言的规则引擎框架。解决商业系统中复杂的业务逻辑硬编码到程序代码中带来不便的问题。drools的出现,可以把业务逻辑独立于程序代码,并且还能实时的更改业务逻辑。支持简单脚本语言的规则实现,也支持通用开发语言的嵌入开发 2.  规则引擎的数据流   1)接收输入数据;   2)解释业务规则;   3)做出业务决策 dro

courage的专栏 5183

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

Drools规则引擎

0. 背景 最近接到一个根据配置的规则进行路由的需求,实现方案中考虑过drools。然后大致研究了一下规则引擎Drools,借助本文进行一个总结和整理。 1. Drools简介 Drools是用Java编写的开源的规则引擎。规则引擎是什么?百度百科里面定义如下:规则引擎是由推理引擎发展而来,是一种嵌入在应用程序中的组件,实现了将业务决策从应用程序代码中分离出来,并使用预定义的语言模块编写...

xiaoyi52的专栏 1220

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Java各种规则引擎

https://www.jianshu.com/p/41ea7a43093c https://segmentfault.com/a/1190000020330741?utm_source=tag-newesthttps://baike.baidu.com/item/%E8%A7%84%E5%88%99%E5%BC%95%E6%93%8E/3076955?fr=aladdin 一、规则引擎使用场景: 用于页面,流程,扩展点实现的选择;输出结果:实现的位置; 编排无数的条件积木和行为积木,达到业务逻

yb223731的博客 2万+

drools_骆驼和春天的Drools决策表

drools 正如我在之前的文章中所展示的那样, JBoss Drools是一个非常有用的规则引擎。 唯一的问题是,对于非技术人员而言,以Rule语言创建规则可能会非常复杂。 这就是为什么可以提供一种简单的方法来创建业务规则的方法-在电子表格中创建决策表! 在下面的示例中,我将向您展示一个非常复杂的业务规则示例,该示例已转换为电子表格中的决策表。 作为后端,我们将有Drools,Camel和S...

cunfu5234的博客 309

Drools规则引擎远程加载规则文件

1.创建一个drools工程: 2.创建一个Dynamic Web Project(主要体现远程加载规则文件,将规则文件放在这个工程中,并配上服务器):   其中,Sample.drl是个规则文件,在浏览器中访问如图所示: 3.再drools工程中创建一个类,我这里类名为:RemoteLoadRule,意思就是远程加载规则文件 代码为: package c

Snow的专栏 6628

java规则引擎框架 可视化

在软件开发中,规则引擎是一种非常重要的技术,它可以帮助开发者实现业务逻辑的灵活配置和动态调整。而Java作为一种流行的编程语言,也有很多优秀的规则引擎框架可供选择。本文将介绍一种Java规则引擎框架,并展示如何通过可视化方式操作规则引擎。 Java规则引擎框架介绍 在众多Java规则引擎框架中,Drools是一个非常知名的...

weixin_42018947的博客 741

规则引擎深度对比,LiteFlow vs Drools

首先我想明确下规则引擎的定义,因为很多小伙伴容易把规则引擎和流程引擎的概念混在一起。规则引擎通常是嵌入在应用程序组件中的,实现了将业务决策从应用程序代码中分离出来,并使用预定义的语义模块编写业务决策。接受数据输入,解释业务规则,并根据业务规则做出业务决策。简单来说就是,规则引擎主要解决易变逻辑和业务耦合的问题,规则驱动逻辑。以前项目内写死在代码里的逻辑用规则引擎可以提出来,随时热变更。而流程引擎实现了将多个业务参与者之间按照某种预定义的规则进行流转,通常需要涉及到角色信息。

z1ztai的博客 1593

Drools6.4简单应用之决策表

1.rule.xls 2.DecisionTableTest.java   /** * caicongyang.com Inc. * Copyright (c) 2004-2016 All Rights Reserved. */ package com.caicongyang.drools.drools; import java.io.File; impo...

xlin 277
上一篇: CSS核心--盒子模型
下一篇: 150天成为JAVA高级程序员?
terryzero
博客等级 码龄19年 700粉丝 232原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值