spring boot + drools
1.关于配置,方式有两种,第一种是直接使用xml配置,第二种是建立configure配置类,两种方式分别如下:
方式一:
1.META-INF 下面增加kmodule.xml
<?xml version="1.0" encoding="UTF-8"?> |
<kmodule xmlns="http://jboss.org/kie/6.0.0/kmodule"> |
<kbase name="rules" packages="com.rule"> |
<ksession name="rulesSession"/> |
</kbase> |
</kmodule> |
KieSession kieSession = kieContainer.newKieSession("rulesSession");
需要的名字
方式二:
书写配置类,如下即可:
@Configuration
public class DroolsConfig {
private static final String RULES_PATH = "rules/"; //指定规则存放的目录
private final KieServices kieServices = KieServices.Factory.get();
@Bean
@ConditionalOnMissingBean
public KieFileSystem kieFileSystem() throws IOException {
KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
Resource[] files = resourcePatternResolver.getResources("classpath*:" + RULES_PATH + "*.*");
String path = null;
for (Resource file : files) {
path = RULES_PATH + file.getFilename();
kieFileSystem.write(ResourceFactory.newClassPathResource(path, "UTF-8"));
}
return kieFileSystem;
}
@Bean
@ConditionalOnMissingBean
public KieContainer kieContainer() throws IOException {
KieRepository kieRepository = kieServices.getRepository();
kieRepository.addKieModule(kieRepository::getDefaultReleaseId);
KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem());
kieBuilder.buildAll();
return kieServices.newKieContainer(kieRepository.getDefaultReleaseId());
}
@Bean
@ConditionalOnMissingBean
public KieBase kieBase() throws IOException {
return kieContainer().getKieBase();
}
@Bean
@ConditionalOnMissingBean
public KieSession kieSession() throws IOException {
return kieContainer().newKieSession();
}
@Bean
@ConditionalOnMissingBean
public KModuleBeanFactoryPostProcessor kiePostProcessor() {
return new KModuleBeanFactoryPostProcessor();
}
}
2.关于规则引擎的几个概念
Working Memory 工作内存
Rule Base 规则库
Inference Engine 推理引擎 :Pattern Mather (匹配器) 、Agenda(议程) 、Execution Engine(执行引擎)
3.规则执行过程
a.将初始数据(fact)输入到工作区域内(working memory)
b.使用匹配器(Pattern Matcher)将规则库中的规则(rule)和数据(fact)匹配,匹配成功的放入到议程(Agenda)中
c. 如果执行规则存在冲突,即同时激活了多个规则,将冲突的规则放入冲突集合(冲突是同时匹配了多条规则,不需要自己处理,drools会自动处理)
d.解决冲突,将激活的规则按照顺序放入议程(agenda)中
e.执行议程(Agenda)中的规则,重复2-4,直到执行议程完毕中的所有规则
3.关于如何获取规则结果
直接传递参数变量,然后将结果给到变量内,执行结束之后返回就好了。
工程代码解析:
配置文件已经给出,看一下执行文件:
@Service
public class RuleService {
@Autowired
private KieBase kieBase;
//调用Drools规则引擎实现信用卡申请
public CreditCardApplyInfo creditCardApply(CreditCardApplyInfo creditCardApplyInfo){
KieSession session = kieBase.newKieSession(); //获取KieSession
session.insert(creditCardApplyInfo); //插入
session.fireAllRules(); //执行规则
session.dispose(); //释放资源
return creditCardApplyInfo;
}
}
规则文件如下:
/*规则名字,任意写,只要在当前文件内唯一即可,可以写中文*/
rule "如果申请人既没房也没车,同时学历大专以下,月薪少于5000,申请不通过"
salience 10 //指定优先级,数值越大优先级越高,不指定的情况下由上到下执行
no-loop true //防止陷入死循环
when
/*规则条件,到工作内存中查找CreditCardApplyInfo对象
里面出来的结果只能是ture或者false
$c是绑定变量名,可以任意命名,官方推荐$符号,定义了绑定变量名,可以在then部分操作fact对象*/
$c:CreditCardApplyInfo(hasHouse == false && hasCar == false &&
education == CreditCardApplyInfo.EDUCATION_1 &&
monthlyIncome<5000)
then
$c.setCheckResult(false); //审核不通过
drools.halt(); //终止规则引擎执行,后续规则不再执行
System.out.println("如果申请人既没房也没车,同时学历大专以下,月薪少于5000,申请不通过");
end
执行结果文件: