drools规则引擎应用笔记

drools规则引擎笔记

一、使用示例

1.规则过滤器

通过AgendaFilter限制fire,默认支持equals、startWith、endWith、Pattern,可自定义AgendaFilter

  final int count = kieSession.fireAllRules(new RuleNameEqualsAgendaFilter("rule1"));

2.session连接池

  • kContainer
KieContainerSessionsPool pool = kContainer.newKieSessionsPool(10);
KieSession kSession = pool.newKieSession();
  • kieBase
final KieSessionsPool kieSessionsPool = kieBase.newKieSessionsPool(10);
KieSession kSession = kieSessionsPool.newKieSession();

drools.7.13.0 新特性

3.debug log

ksession.addEventListener( new DebugRuleRuntimeEventListener() );
  • pom.xml
<dependency>
  <groupId>ch.qos.logback</groupId>
  <artifactId>logback-classic</artifactId>
  <version>${logback.version}</version>
</dependency>
  • logback.xml
<configuration>
  <logger name="org.drools" level="debug"/>
  ...
<configuration>

Drools engine event listeners and debug logging

4.规则内容与模型互转

    @Test
    public void testPackageDescr() {

        // 默认生成drl
        final PackageDescr descr = DescrFactory.newPackage().name("com.example.demo")
                .newImport().target(java.util.List.class.getName()).end()
                .newGlobal().type(java.util.List.class.getName()).identifier("count").end()
                .newRule().name("rule1")
                .attribute("enabled","true")
                .lhs()
                .pattern(Person.class.getName()).id("$p", false).constraint("name==\"张三\"").end()
                .end()
                .rhs("System.out.println($p);")
                .end()
                .end()
                .getDescr();

        final String drl = new DrlDumper().dump(descr);
        System.out.println(drl);

        System.out.println("=================================================================");

        // drl解析成模型
        DrlParser drlParser = new DrlParser();
        final StringReader reader = new StringReader(drl);
        try {
            // 语法结构解析,不做环境校验(例如Person类是否存在)
            final PackageDescr descr1 = drlParser.parse(reader);
            if (drlParser.hasErrors()) {
                System.out.println(drlParser.getErrors());
                throw new DroolsParserException("The model drl " + drl + " is not valid");
            } else {
                final String drl1 = new DrlDumper().dump(descr1);
                System.out.println(drl1);
            }
        } catch (DroolsParserException e) {
            e.printStackTrace();
        }

    }

二、规则编译及动态加载

1.校验jar包中的规则

  • KieContainer方式
        KieServices ks = KieServices.Factory.get();
        ReleaseId releaseId = ks.newReleaseId("com.example", "demo", "1.0");
        final KieContainer kieContainer = ks.newKieContainer(releaseId);
        final Results results = kieContainer.verify();
        final List<Message> messages = results.getMessages(Message.Level.ERROR);
  • KieHelper方式
  KieHelper kieHelper = new KieHelper();
  kieHelper.addContent(content, ResourceType.DRL);
  Results results = kieHelper.verify();
	if (results.hasMessages(Message.Level.WARNING, Message.Level.ERROR)) {
	    List<Message> messages = results.getMessages(Message.Level.WARNING, Message.Level.ERROR);
	    System.out.println(messages);
    }

2.自定义classloader

  • KieBuilder 方式
KieServices ks = KieServices.Factory.get();
final KieBuilder kieBuilder = ks.newKieBuilder(kfs, classLoader)
  • KieHelper方式
KieHelper kieHelper = new KieHelper();
kieHelper.setClassLoader(classLoader);

3.动态生成kjar并编译规则

    @Test
    public void buildRulesTest() {
        KieServices ks = KieServices.Factory.get();

        ReleaseId releaseId = ks.newReleaseId("com.example", "demo", "1.0");
        // kieModule模型
        KieModuleModel kieModuleModel = ks.newKieModuleModel();
        kieModuleModel.newKieBaseModel()
                .addPackage("com.example.demo")
                .setDefault(true)
                .newKieSessionModel("session")
                .setType(KieSessionModel.KieSessionType.STATEFUL);
        // 内存文件系统
        KieFileSystem kfs = ks.newKieFileSystem()
                .generateAndWritePomXML(releaseId)
                .write("src/main/resources/com/example/demo/r1.drl", "package com.example.demo;\n" +
                        "\n" +
                        "import com.example.drools.Person \n" +
                        "dialect  \"mvel\"\n" +
                        "\n" +
                        "\n" +
                        "\n" +
                        "global java.lang.Integer count1;\n" +
                        "\n" +
                        "rule \"rule1\"\n" +
                        "    when\n" +
                        "    $p:Person(name == \"张三\")" +
                        "    then\n" +
                        "    System.out.println(\"rule1\");\n" +
                        "end\n")
                .writeKModuleXML(kieModuleModel.toXML());
        /**
         * 编译并自动添加到repository仓库
         * @see org.drools.compiler.kie.builder.impl.KieBuilderImpl#buildKieProject(org.drools.compiler.kie.builder.impl.ResultsImpl, org.drools.compiler.kie.builder.impl.KieModuleKieProject, org.drools.compiler.compiler.io.memory.MemoryFileSystem)
          */
        final KieBuilder kieBuilder = ks.newKieBuilder(kfs).buildAll();

        final Results results = kieBuilder.getResults();
        final boolean b = results.hasMessages(Message.Level.ERROR);
        if (b) {
            System.out.println(results.getMessages());
            throw new RuntimeException(results.toString());
        } else {
            final KieContainer kieContainer = ks.newKieContainer(releaseId);
            KieSession ksession = kieContainer.newKieSession("session");
            final Person person = new Person();
            person.setName("张三");
            person.setAge(21);
            ksession.insert(person);
            int count = ksession.fireAllRules();
            ksession.dispose();
            System.out.println(count);
        }
    }

4.动态加载自定义类和规则文件

  • 常量
    private static final String FILE_SEPARATOR = "/";
    private static final String SOURCE_PATH = "src/main/java";
    private static final String RESOURCE_PATH = "src/main/resources";
  • 动态加载自定义类
        final KieHelper kieHelper = new KieHelper();
        // 全限类名
        String fullQualifiedName = "com.example.Test";
        // java源代码
        String code = "...";
        final Resource resource = ResourceFactory.newByteArrayResource(code.getBytes(StandardCharsets.UTF_8));
        resource.setSourcePath(SOURCE_PATH + FILE_SEPARATOR + fullQualifiedName.replace(".", FILE_SEPARATOR) + ".java");
        // 解决规则文件函数(本质是通过JavaCompiler编译java源代码生成class字节码)的源码编译依赖问题
        kieHelper.addResource(resource, ResourceType.JAVA);
  • 动态加载规则文件
String drl = "...";
kieHelper.addContent(drl, ResourceType.DRL);
  • 动态赋值及规则调用
        // 注意:不要执行 kieHelper.build(),此为无用功,且此处的kieBase和kieContainer.getKieBase()虽然均为defaultKieBase,但由于不是同一个kieContainer,所以它们也不是统一kieBase
        // final KieBase kieBase = kieHelper.build();
        final KieContainer kieContainer = kieHelper.getKieContainer();
        final ClassLoader classLoader = kieContainer.getClassLoader();
        final Class<?> aClass = classLoader.loadClass("com.example.TestInfo11");
        // 反射操作
        final Object obj = aClass.newInstance();
 		/**
         * 注意:每次调用kieHelper.getKieContainer()都会重新编译规则和类;kieHelper.build()本质也是调用kieHelper.getKieContainer()
         * ,所以classloader会不断变化,动态编译类的class对象也不相同。
         */
        final KieSession kieSession = kieContainer.newKieSession();
        kieSession.insert(obj);
        final int count = kieSession.fireAllRules();
        System.out.println(count);
        kieSession.dispose();

视频:
Drools7规则引擎从入门到精通

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

搬山境KL攻城狮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值