透過將業務規則配置的設定檔中,可以精簡程式碼,同時已於維護,當規則修改時,只需要修改設定檔即可。 easy-rules是一個小巧的規則引擎,支援spring的SPEL表達式,同時也支援 Apache JEXL 表達式和 MVL 表達式。
在專案的gradle中增加依賴關係。
build.gradle:
name: "age rule"plugins {
id 'org.springframework.boot' version '3.0.5'
id 'io.spring.dependency-management ' version '1.1.0'
id 'java'
}group = 'cn.springcamp'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17 'configurations {
dependencies {
compileOnly {
extendsFrom annotationProcessor
}
testCompile ies {
mavenCentral()
}implementation "org.springframework.boot:spring-boot-starter-json"
implementation 'org.jeasy:easy-rules-core:4.1.0'
implementation 'org.spring-boot-starter-json"
implementation 'org.springframework.boot:springsp -starter-validation'implementation 'org.jeasy:easy-rules-spel:4.1.0'
mavenBom "org.springframework.cloud:spring-cloud-dependencies:2022.0.1"
implementation 'org. jeasy:easy-rules-support:4.1.0'
annotationProcessor 'org.projectlombok:lombok'
testAnnotationProcessor 'org.projectlombok:lombok'
testAnnotationProcessor 'org.projectlombok:lombok'
-test"
testImplementation 'org.junit.vintage:junit-vintage-engine'
testImplementation 'org.junit.vintage:junit-vintage-engine'
}
#dependencyManagement {
imports {}
三、設定檔
}
##testtest {##> }
範例程式將業務規則放到設定檔中,業務規則設定檔(demo-rule.yml)程式碼:
condition: "#person.getAdult() == false"
actions:- "T( java.lang.System).out.println(\"Shop: Sorry, you are not allowed to buy alcohol\")"- "#person.setAdult(true)"
這個spring bean中的getAdult()判斷是否滿足規則,滿足規則時呼叫三個方法。
- "#person.setAge (18)"
---
name: "alcohol rule"
description: ""
priority: 1
condition: "#person.getAdult() == true"
actions:
- "T(java.lang.System).out.println(\"Shop: you are now allowed to buy alcohol\")"
#設定檔中的規則透過condition 進行配置,當滿足規則時,會呼叫actions 中配置的動作。
範例專案使用了spring的SPEL表達式進行規則配置,設定檔中配置了2個規則,第一個規則透過
person
在spring-boot本身的設定檔中application.yml 設定規則檔:
rule:
skip-on-first-failed-rule: true
skip-on-first-non-triggered-rule: true
rules:- rule-id: "demo"location: "classpath:demo-rule.yml"
這個spring的設定類別對規則引擎進行設定:
四、程式碼中對規則引擎進行設定
透過
RuleEngineConfig
@Slf4j @EnableConfigurationProperties(RuleEngineConfigProperties.class) @Configuration public class RuleEngineConfig implements BeanFactoryAware { @Autowired(required = false) private List<RuleListener> ruleListeners; @Autowired(required = false) private List<RulesEngineListener> rulesEngineListeners; private BeanFactory beanFactory; @Bean public RulesEngineParameters rulesEngineParameters(RuleEngineConfigProperties properties) { RulesEngineParameters parameters = new RulesEngineParameters(); parameters.setSkipOnFirstAppliedRule(properties.isSkipOnFirstAppliedRule()); parameters.setSkipOnFirstFailedRule(properties.isSkipOnFirstFailedRule()); parameters.setSkipOnFirstNonTriggeredRule(properties.isSkipOnFirstNonTriggeredRule()); return parameters; } @Bean public RulesEngine rulesEngine(RulesEngineParameters rulesEngineParameters) { DefaultRulesEngine rulesEngine = new DefaultRulesEngine(rulesEngineParameters); if (!CollectionUtils.isEmpty(ruleListeners)) { rulesEngine.registerRuleListeners(ruleListeners); } if (!CollectionUtils.isEmpty(rulesEngineListeners)) { rulesEngine.registerRulesEngineListeners(rulesEngineListeners); } return rulesEngine; } @Bean public BeanResolver beanResolver() { return new BeanFactoryResolver(beanFactory); } @Bean public RuleEngineTemplate ruleEngineTemplate(RuleEngineConfigProperties properties, RulesEngine rulesEngine) { RuleEngineTemplate ruleEngineTemplate = new RuleEngineTemplate(); ruleEngineTemplate.setBeanResolver(beanResolver()); ruleEngineTemplate.setProperties(properties); ruleEngineTemplate.setRulesEngine(rulesEngine); return ruleEngineTemplate; } @Bean public RuleListener defaultRuleListener() { return new RuleListener() { @Override public boolean beforeEvaluate(Rule rule, Facts facts) { return true; } @Override public void afterEvaluate(Rule rule, Facts facts, boolean b) { log.info("-----------------afterEvaluate-----------------"); log.info(rule.getName() + rule.getDescription() + facts.toString()); } @Override public void beforeExecute(Rule rule, Facts facts) { log.info("-----------------beforeExecute-----------------"); log.info(rule.getName() + rule.getDescription() + facts.toString()); } @Override public void onSuccess(Rule rule, Facts facts) { log.info("-----------------onSuccess-----------------"); log.info(rule.getName() + rule.getDescription() + facts.toString()); } @Override public void onFailure(Rule rule, Facts facts, Exception e) { log.info("-----------------onFailure-----------------"); log.info(rule.getName() + "----------" + rule.getDescription() + facts.toString() + e.toString()); } }; } @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { this.beanFactory = beanFactory; } }
這個spring bean,透過ruleEngineTemplate觸發規則引擎的執行。 五、執行規則引擎
ruleEngineTemplate
配置好後,我們可以在業務程式碼中執行規則引擎,處理設定檔中設定的業務規則:
@SpringBootApplication public class Application implements CommandLineRunner { @Autowired RuleEngineTemplate ruleEngineTemplate; public static void main(String[] args) { SpringApplication.run(Application.class, args); } @Override public void run(String... args) { Person person = new Person(); Facts facts = new Facts(); facts.put("person", person); ruleEngineTemplate.fire("demo", facts); } }
程式執行後可以看到控制台裡列印了 Shop: Sorry, you are not allowed to buy alcohol
,這個內容對應的是我們在規則文件中的actions中配置的
,說明規則成功執行了。
以上是SpringBoot整合easy-rules規則引擎的流程是什麼的詳細內容。更多資訊請關注PHP中文網其他相關文章!