Click on “Yao Dao Source Code” above and select “Set as Star”
Does she care about the front wave or the back wave?
A wave that can wave is a good wave!
Update articles every day at 10:33, lose a million bits of hair every day…
Source code boutique column
-
Original | Java 2021 Super God Road, very liver~
-
An open source project with detailed annotations in Chinese
-
RPC framework Dubbo source code analysis
-
Network application framework Netty source code analysis
-
Message middleware RocketMQ source code analysis
-
Database middleware Sharding-JDBC and MyCAT source code analysis
-
Job Scheduling Middleware Elastic-Job Source Code Analysis
-
Distributed transaction middleware TCC-Transaction source code analysis
-
Eureka and Hystrix source code analysis
-
Java Concurrency Source Code
Source: JAVA Risun
-
Introduce dependencies
-
Drools configuration class
-
Add business model
-
Define drools rules
-
Add Service layer
-
Add Controller
-
have a test
-
Summarize
Now there is such a demand, online shopping needs to calculate product discounts according to different rules, such as 5% discount for VIP customers, 10% discount for purchases exceeding 1,000 yuan, etc., and these rules may change at any time, or even increase new rules. Faced with this demand, how do you realize it? Could it be that when the calculation rules change, the business code must be modified, retested, and launched.
In fact, we can implement it through a rule engine. Drools is an open source business rule engine that can be easily integrated with spring boot applications. In this article, we will use Drools to realize the above-mentioned requirements.
Introducing dependencies
We create a spring boot application and add drools-related dependencies to the pom, as follows:
<dependency> <groupId>org.drools</groupId> <artifactId>drools-core</artifactId> <version>7.59.0.Final</version> </dependency> <dependency> <groupId>org.drools</groupId> <artifactId>drools-compiler</artifactId> <version>7.59.0.Final</version> </dependency> <dependency> <groupId>org.drools</groupId> <artifactId>drools-decisiontables</artifactId> <version>7.59.0.Final</version> </dependency>
Background management system + user applet based on Spring Boot + MyBatis Plus + Vue & amp; Element, supports RBAC dynamic permissions, multi-tenancy, data permissions, workflow, three-party login, payment, SMS, mall and other functions
Project address: https://github.com/YunaiV/ruoyi-vue-pro
Video tutorial: https://doc.iocoder.cn/video/
Drools configuration class
Create a configuration java class called DroolsConfig
.
@Configuration public class DroolsConfig { // specify the path to the rule file private static final String RULES_CUSTOMER_RULES_DRL = "rules/customer-discount.drl"; private static final KieServices kieServices = KieServices.Factory.get(); @Bean public KieContainer kieContainer() { KieFileSystem kieFileSystem = kieServices. newKieFileSystem(); kieFileSystem.write(ResourceFactory.newClassPathResource(RULES_CUSTOMER_RULES_DRL)); KieBuilder kb = kieServices. newKieBuilder(kieFileSystem); kb.buildAll(); KieModule kieModule = kb. getKieModule(); KieContainer kieContainer = kieServices.newKieContainer(kieModule.getReleaseId()); return kieContainer; } }
-
A
Spring Bean
ofKieContainer
is defined, andKieContainer
is used to load the application under the/resources
folder rule files to build the rules engine. -
Creates a
KieFileSystem
instance and configures the rule engine and loads the rule’sDRL
file from the application’s resource directory. -
Use
KieBuilder
instance to builddrools
module. We can use KieServive singleton instance to createKieBuilder
instance. -
Finally, use
KieService
to create aKieContainer
and configure it as aspring bean
.
Background management system + user applet based on Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & amp; Element, supporting RBAC dynamic permissions, multi-tenancy, data permissions, workflow, three-party login, payment, SMS, mall and other functions
Project address: https://github.com/YunaiV/yudao-cloud
Video tutorial: https://doc.iocoder.cn/video/
Add business model
Create an order object OrderRequest
. The fields in this class are then sent as input information to the defined drools
rules to calculate the discount amount for a given customer order.
@Getter @Setter public class OrderRequest { /** * client number */ private String customerNumber; /** * age */ private Integer age; /** * order amount */ private Integer amount; /** * Customer type */ private CustomerType customerType; }
In addition, define an enumeration of customer type CustomerType
from which the rules engine will calculate the customer order discount percentage, as shown below.
public enum CustomerType { LOYAL, NEW, DISSATISFIED; public String getValue() { return this.toString(); } }
Finally, create an order discount class OrderDiscount
to represent the calculated final discount, as shown below.
@Getter @Setter public class OrderDiscount { /** * Discount */ private Integer discount = 0; }
We will return the calculated discount using the above response object.
Define drools rules
The previous DroolsConfig
class specifies the drools
rule directory, now we add customer in the
file, which defines the corresponding rules./src/main/resources/rules
directory -discount.drl
Although this drl
file is not a java file, it is still easy to understand.
-
We use a global parameter called
orderDiscount
that can be shared between multiple rules. Pay attention to Gongzhong account: code ape technology column, reply keywords: 1111 Get Ali’s internal java performance tuning manual! -
A
drl
file can contain one or more rules. We can use themvel
syntax to specify rules. Additionally, each rule is described using therule
keyword. -
Each rule uses
when-then
syntax to define the conditions of the rule. -
Based on the input value of the order request, we are adding a discount to the result. Each rule adds an additional discount to the global result variable if the rule expression matches.
The complete rule source code is as follows:
import com.alvin.drools.model.OrderRequest; import com.alvin.drools.model.CustomerType; global com.alvin.drools.model.OrderDiscount orderDiscount; dialect "mvel" // Rule 1: Judging by age rule "Age based discount" when // When the customer's age is under 20 or over 50 OrderRequest(age < 20 || age > 50) then // add 10% discount System.out.println("===========Adding 10% discount for Kids/ senior customer==============="); orderDiscount.setDiscount(orderDiscount.getDiscount() + 10); end // Rule 2: Rules based on customer type rule "Customer type based discount - Loyal customer" when // When the customer type is LOYAL OrderRequest(customerType. getValue == "LOYAL") then // add 5% discount System.out.println("==========Adding 5% discount for LOYAL customer==============="); orderDiscount.setDiscount(orderDiscount.getDiscount() + 5); end rule "Customer type based discount - others" when OrderRequest(customerType. getValue != "LOYAL") then System.out.println("===========Adding 3% discount for NEW or DISSATISFIED customer==============="); orderDiscount.setDiscount(orderDiscount.getDiscount() + 3); end rule "Amount based discount" when OrderRequest(amount > 1000L) then System.out.println("===========Adding 5% discount for amount more than 1000$==============="); orderDiscount.setDiscount(orderDiscount.getDiscount() + 5); end
Add Service layer
Create a service class called OrderDiscountService
, as follows:.
@Service public class OrderDiscountService { @Autowired private KieContainer kieContainer; public OrderDiscount getDiscount(OrderRequest orderRequest) { OrderDiscount orderDiscount = new OrderDiscount(); // start the session KieSession kieSession = kieContainer. newKieSession(); // set discount object kieSession.setGlobal("orderDiscount", orderDiscount); // set the order object kieSession.insert(orderRequest); // trigger rule kieSession.fireAllRules(); // abort the session kieSession.dispose(); return order Discount; } }
-
Inject a
KieContainer
instance and create aKieSession
instance. -
A global parameter of type
OrderDiscount
is set, which will save the rule execution result. -
Use the
insert()
method to pass the request object to thedrl
file. -
Call the
fireAllRules()
method to fire all rules. -
Finally, terminate the session by calling the
dispose()
method ofKieSession
.
Add Controller
Create a Controller
class named OrderDiscountController
, the specific code is as follows:
@RestController public class OrderDiscountController { @Autowired private OrderDiscountService orderDiscountService; @PostMapping("/get-discount") public ResponseEntity<OrderDiscount> getDiscount(@RequestBody OrderRequest orderRequest) { OrderDiscount discount = orderDiscountService. getDiscount(orderRequest); return new ResponseEntity<>(discount, HttpStatus.OK); } }
Test it
Run the spring boot
application and access the REST API endpoint by sending the customer order request JSON.
-
For
LOYAL
customer type with age < 20 and amount > 1000, we should get discount of20%
according to the rules we defined.
Summary
We have simply implemented such a discount business through the drools
rule engine. Now the product manager asks you to add a rule, for example, if the address is Hangzhou plus 10% discount, you can directly change the drl file. Others Just spend time fishing, haha~~. You can go to the official website to explore more about the usage of drools
.
Welcome to join my knowledge planet, discuss architecture and exchange source code together. How to join, Long press the QR code below:
The source code has been updated on Knowledge Planet and the analysis is as follows:
The recently updated series “Introduction to Taro SpringBoot 2.X” has more than 101 articles, covering MyBatis, Redis, MongoDB, ES, sub-database and sub-table, read-write separation, SpringMVC, Webflux, permissions, WebSocket, Dubbo, RabbitMQ, RocketMQ , Kafka, performance testing, etc.
Provides a SpringBoot example with nearly 3W lines of code, and an e-commerce microservice project with more than 4W lines of code.
How to get it: Click “Looking“, follow the official account and reply to 666 to receive, more content will be provided one after another.
If the article is helpful, please read it and forward it. Thank you for your support (*^__^*)