Maison  >  Article  >  Java  >  Quel est le processus permettant à SpringBoot d'intégrer le moteur de règles simples ?

Quel est le processus permettant à SpringBoot d'intégrer le moteur de règles simples ?

王林
王林avant
2023-05-15 16:25:061083parcourir

1. Présentation

En configurant les règles métier dans le fichier de configuration, le code peut être rationalisé et maintenu. Lorsque les règles sont modifiées, seul le fichier de configuration doit être modifié. easy-rules est un moteur de règles compact qui prend en charge les expressions SPEL de Spring, ainsi que les expressions Apache JEXL et MVL.

2. Ajouter des dépendances au projet

Ajouter des dépendances dans le niveau du projet.

build.gradle:

plugins {
identifiant 'org.springframework.boot' version '3.0.5'
identifiant 'io.spring.dependency-management' version '1.1.0'
identifiant 'java'
}

group = 'cn.springcamp'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'

configurations {
  compileOnly {
                        extendsFrom testAnnotationProcessor
}
}

dépôts {
mavenCentral()

}


dépendances {
implémentation "org.springframework.boot:spring-boot-starter-json"

implémentation 'org.springframework.boot:spring-boot-starter-validation'

implémentation 'jeasy:easy-rules-core : 4.1.0'
implémentation 'org.jeasy:easy-rules-spel:4.1.0'
implémentation 'org.jeasy:easy-rules-support:4.1.0'
annotationProcessor 'org .projectlombok:lombok'
testAnnotationProcessor ' org.projectlombok:lombok'
testImplementation "org.springframework.boot:spring-boot-starter-test"
testImplementation 'org.junit.vintage:junit-vintage-engine'
testImplementation 'org .junit.vintage:junit-vintage -engine'
}

dependencyManagement {
importations {

mavenBom "org.springframework.cloud:spring-cloud-dependencies:2022.0.1"

}
}

test {
tPlatform()

}



3. Fichier de configuration

L'exemple de programme place les règles métier dans le fichier de configuration. Le fichier de configuration des règles métier (demo-rule.yml) code :

nom : "règle d'âge"

description : ""
priorité : 1

condition. : "#person.getAdult() == false"
actions:
- "T(java.lang.System).out.println("Boutique : Désolé, vous n'êtes pas autorisé à acheter de l'alcool" )"
- "# person.setAdult(true)"
- "#person.setAge(18)"
---
nom : "règle d'alcool"
description : ""
priorité : 1
condition : "#person .getAdult() == true"
actions:
- "T(java.lang.System).out.println("Boutique : vous êtes désormais autorisé à acheter de l'alcool")"


Les règles du fichier de configuration satisfont à la condition Configurer, et quand le Si les règles sont respectées, les actions configurées dans actions seront appelées.

L'exemple de projet utilise l'expression SPEL de Spring pour la configuration des règles. Deux règles sont configurées dans le fichier de configuration. La première règle détermine si la règle est respectée via getAdult() dans le bean Spring person. sont appelés lorsque les règles sont respectées.

Configurez le fichier de règles dans application.yml dans le fichier de configuration de spring-boot lui-même :

person这个spring bean中的getAdult()判断是否满足规则,满足规则时调用三个方法。

在spring-boot本身的配置文件中 application.yml 配置规则文件:

rule:
  skip-on-first-failed-rule: true
  skip-on-first-applied-rule: false
  skip-on-first-non-triggered-rule: true
  rules:
    - rule-id: "demo"
      rule-file-location: "classpath:demo-rule.yml"

四、代码中对规则引擎进行配置

通过 RuleEngineConfig这个spring的配置类对规则引擎进行配置:

@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;
    }
}

配置文件中配置了 ruleEngineTemplate这个spring bean,通过ruleEngineTemplate触发规则引擎的执行。

五、执行规则引擎

ruleEngineTemplate配置好后,我们可以在业务代码中执行规则引擎,处理配置文件中配置的业务规则:

最为演示,我们将规则引擎的执行代码放到了 Application 的 run 方法中,程序启动后立即执行规则引擎:

@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中配置的 "T(java.lang.System).out.println("Shop: Sorry, you are not allowed to buy alcohol")"

rule:🎜 skip-on-first-failed-rule: true🎜 skip-on-first-applied-rule: false🎜 sauter la première règle non déclenchée : true🎜 règles :🎜 - identifiant de règle : "demo"🎜 emplacement du fichier de règles : "classpath:demo-rule.yml"🎜🎜🎜 Quatrièmement, exécutez le moteur de règles dans le code Configuration🎜🎜Configurez le moteur de règles via la classe de configuration Spring RuleEngineConfig : 🎜rrreee🎜Le bean Spring ruleEngineTemplate est configuré dans le fichier de configuration, et l'exécution du le moteur de règles est déclenché via RuleEngineTemplate . 🎜🎜5. Exécution du moteur de règles🎜🎜Une fois ruleEngineTemplate configuré, nous pouvons exécuter le moteur de règles dans le code métier et traiter les règles métier configurées dans le fichier de configuration : 🎜🎜À titre de démonstration, nous utiliserons le moteur de règles Le code d'exécution est placé dans la méthode d'exécution de l'Application. Le moteur de règles est exécuté immédiatement après le démarrage du programme : 🎜rrreee🎜Après l'exécution du programme, vous pouvez voir que Shop : Désolé, vous n'êtes pas autorisé à acheter de l'alcool est imprimé sur la console, ce contenu correspond au "T(java.lang.System).out.println("Boutique : Désolé, vous n'êtes pas autorisé à acheter de l'alcool. acheter de l'alcool")" code>, indiquant que la règle a été exécutée avec succès. 🎜

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer