-
Notifications
You must be signed in to change notification settings - Fork 0
/
search.xml
323 lines (155 loc) · 755 KB
/
search.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title>关于Logback+MyBatis日志输出的一些思考</title>
<link href="/2022/09/29/guan-yu-mybatis-ri-zhi-shu-chu-de-yi-xie-si-kao/"/>
<url>/2022/09/29/guan-yu-mybatis-ri-zhi-shu-chu-de-yi-xie-si-kao/</url>
<content type="html"><![CDATA[<h1 id="一-环境"><a href="#一-环境" class="headerlink" title="一.环境"></a>一.环境</h1><p>MyBatis-Plus:3.4.3.4</p><p>SpringBoot:2.5.8</p><p>Logback:1.2.9(SpringBoot自动依赖)</p><h1 id="二-问题"><a href="#二-问题" class="headerlink" title="二.问题"></a>二.问题</h1><ol><li>sql语句和业务日志合在一起,sql太多会影响业务日志分析,因为平时不需要看,出问题的时候才用上,所以sql日志和业务日志应该分成不同的文件记录</li><li>有些场景需要开发的时候同时在IDE控制台打印sql执行语句、输出sql到日志文件中</li><li>日志分开后,又会导致查问题时不容易分清楚是否是同一次请求交易,简单通过线程名、时间点来区分也不方便而且容易出错</li><li>有时数据会因为事务等原因导致写入失效,需要查看事务日志</li><li>业务模块很多的单体应用,所以日志糅杂在一起,查看不方便,按照业务模块记录到不同的日志文件中</li></ol><h1 id="三-解答"><a href="#三-解答" class="headerlink" title="三.解答"></a>三.解答</h1><p>先贴出logback.xml的配置,后面的解答就是此配置文件中的内容</p><details><summary><b>展开查看logback配置</b></summary><pre><code><pre class="line-numbers language-xml" data-language="xml"><code class="language-xml"><span class="token prolog"><?xml version="1.0" encoding="UTF-8"?></span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>configuration</span> <span class="token attr-name">scan</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>true<span class="token punctuation">"</span></span> <span class="token attr-name">scanPeriod</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>60 seconds<span class="token punctuation">"</span></span> <span class="token attr-name">debug</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>false<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>property</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>logger.path<span class="token punctuation">"</span></span> <span class="token attr-name">value</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>/home/logs<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span> <span class="token comment"><!-- 彩色日志 --></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>conversionRule</span> <span class="token attr-name">conversionWord</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>clr<span class="token punctuation">"</span></span> <span class="token attr-name">converterClass</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>org.springframework.boot.logging.logback.ColorConverter<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>conversionRule</span> <span class="token attr-name">conversionWord</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>wex<span class="token punctuation">"</span></span> <span class="token attr-name">converterClass</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>conversionRule</span> <span class="token attr-name">conversionWord</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>wEx<span class="token punctuation">"</span></span> <span class="token attr-name">converterClass</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span> <span class="token comment"><!-- 彩色日志格式 --></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>property</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>CONSOLE_LOG_PATTERN<span class="token punctuation">"</span></span> <span class="token attr-name">value</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}-%line){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}<span class="token punctuation">"</span></span><span class="token punctuation">/></span></span> <span class="token comment"><!--输出到控制台--></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>appender</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>CONSOLE<span class="token punctuation">"</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>ch.qos.logback.core.ConsoleAppender<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>filter</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>ch.qos.logback.classic.filter.ThresholdFilter<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>level</span><span class="token punctuation">></span></span>DEBUG<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>level</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>filter</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>encoder</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>Pattern</span><span class="token punctuation">></span></span>${CONSOLE_LOG_PATTERN}<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>Pattern</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>charset</span><span class="token punctuation">></span></span>UTF-8<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>charset</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>encoder</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>appender</span><span class="token punctuation">></span></span> <span class="token comment"><!--输出到文件--></span> <span class="token comment"><!-- 时间滚动输出 level为 DEBUG 日志 --></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>appender</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>DEBUG_FILE<span class="token punctuation">"</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>ch.qos.logback.core.rolling.RollingFileAppender<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>file</span><span class="token punctuation">></span></span>${logger.path}/log_debug.log<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>file</span><span class="token punctuation">></span></span> <span class="token comment"><!--日志文件输出格式--></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>encoder</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>pattern</span><span class="token punctuation">></span></span>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}-%line - %m%n<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>pattern</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>charset</span><span class="token punctuation">></span></span>UTF-8<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>charset</span><span class="token punctuation">></span></span> <span class="token comment"><!-- 设置字符集 --></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>encoder</span><span class="token punctuation">></span></span> <span class="token comment"><!-- 日志记录器的滚动策略,按日期,按大小记录 --></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>rollingPolicy</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>ch.qos.logback.core.rolling.TimeBasedRollingPolicy<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token comment"><!-- 日志归档 --></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>fileNamePattern</span><span class="token punctuation">></span></span>${logger.path}/debug/log-debug-%d{yyyy-MM-dd}.%i.log<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>fileNamePattern</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>timeBasedFileNamingAndTriggeringPolicy</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>maxFileSize</span><span class="token punctuation">></span></span>100MB<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>maxFileSize</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>timeBasedFileNamingAndTriggeringPolicy</span><span class="token punctuation">></span></span> <span class="token comment"><!--日志文件保留天数--></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>maxHistory</span><span class="token punctuation">></span></span>15<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>maxHistory</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>rollingPolicy</span><span class="token punctuation">></span></span> <span class="token comment"><!-- 此日志文件只记录debug级别的 --></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>filter</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>ch.qos.logback.classic.filter.LevelFilter<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>level</span><span class="token punctuation">></span></span>debug<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>level</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>onMatch</span><span class="token punctuation">></span></span>ACCEPT<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>onMatch</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>onMismatch</span><span class="token punctuation">></span></span>DENY<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>onMismatch</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>filter</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>appender</span><span class="token punctuation">></span></span> <span class="token comment"><!-- 时间滚动输出 level为 INFO 日志 --></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>appender</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>INFO_FILE<span class="token punctuation">"</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>ch.qos.logback.core.rolling.RollingFileAppender<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token comment"><!-- 正在记录的日志文件的路径及文件名 --></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>file</span><span class="token punctuation">></span></span>${logger.path}/log_info.log<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>file</span><span class="token punctuation">></span></span> <span class="token comment"><!--日志文件输出格式--></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>encoder</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>pattern</span><span class="token punctuation">></span></span>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}-%line - %m%n<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>pattern</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>charset</span><span class="token punctuation">></span></span>UTF-8<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>charset</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>encoder</span><span class="token punctuation">></span></span> <span class="token comment"><!-- 日志记录器的滚动策略,按日期,按大小记录 --></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>rollingPolicy</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>ch.qos.logback.core.rolling.TimeBasedRollingPolicy<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token comment"><!-- 每天日志归档路径以及格式 --></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>fileNamePattern</span><span class="token punctuation">></span></span>${logger.path}/info/log-info-%d{yyyy-MM-dd}.%i.log<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>fileNamePattern</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>timeBasedFileNamingAndTriggeringPolicy</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>maxFileSize</span><span class="token punctuation">></span></span>100MB<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>maxFileSize</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>timeBasedFileNamingAndTriggeringPolicy</span><span class="token punctuation">></span></span> <span class="token comment"><!--日志文件保留天数--></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>maxHistory</span><span class="token punctuation">></span></span>15<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>maxHistory</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>rollingPolicy</span><span class="token punctuation">></span></span> <span class="token comment"><!-- 此日志文件只记录info级别的 --></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>filter</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>ch.qos.logback.classic.filter.LevelFilter<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>level</span><span class="token punctuation">></span></span>info<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>level</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>onMatch</span><span class="token punctuation">></span></span>ACCEPT<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>onMatch</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>onMismatch</span><span class="token punctuation">></span></span>DENY<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>onMismatch</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>filter</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>appender</span><span class="token punctuation">></span></span> <span class="token comment"><!-- 时间滚动输出 level为 WARN 日志 --></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>appender</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>WARN_FILE<span class="token punctuation">"</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>ch.qos.logback.core.rolling.RollingFileAppender<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token comment"><!-- 正在记录的日志文件的路径及文件名 --></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>file</span><span class="token punctuation">></span></span>${logger.path}/log_warn.log<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>file</span><span class="token punctuation">></span></span> <span class="token comment"><!--日志文件输出格式--></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>encoder</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>pattern</span><span class="token punctuation">></span></span>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}-%line - %m%n<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>pattern</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>charset</span><span class="token punctuation">></span></span>UTF-8<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>charset</span><span class="token punctuation">></span></span> <span class="token comment"><!-- 此处设置字符集 --></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>encoder</span><span class="token punctuation">></span></span> <span class="token comment"><!-- 日志记录器的滚动策略,按日期,按大小记录 --></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>rollingPolicy</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>ch.qos.logback.core.rolling.TimeBasedRollingPolicy<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>fileNamePattern</span><span class="token punctuation">></span></span>${logger.path}/warn/log-warn-%d{yyyy-MM-dd}.%i.log<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>fileNamePattern</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>timeBasedFileNamingAndTriggeringPolicy</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>maxFileSize</span><span class="token punctuation">></span></span>100MB<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>maxFileSize</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>timeBasedFileNamingAndTriggeringPolicy</span><span class="token punctuation">></span></span> <span class="token comment"><!--日志文件保留天数--></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>maxHistory</span><span class="token punctuation">></span></span>15<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>maxHistory</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>rollingPolicy</span><span class="token punctuation">></span></span> <span class="token comment"><!-- 此日志文件只记录warn级别的 --></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>filter</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>ch.qos.logback.classic.filter.LevelFilter<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>level</span><span class="token punctuation">></span></span>warn<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>level</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>onMatch</span><span class="token punctuation">></span></span>ACCEPT<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>onMatch</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>onMismatch</span><span class="token punctuation">></span></span>DENY<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>onMismatch</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>filter</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>appender</span><span class="token punctuation">></span></span> <span class="token comment"><!-- 时间滚动输出 level为 ERROR 日志 --></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>appender</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>ERROR_FILE<span class="token punctuation">"</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>ch.qos.logback.core.rolling.RollingFileAppender<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token comment"><!-- 正在记录的日志文件的路径及文件名 --></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>file</span><span class="token punctuation">></span></span>${logger.path}/log_error.log<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>file</span><span class="token punctuation">></span></span> <span class="token comment"><!--日志文件输出格式--></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>encoder</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>pattern</span><span class="token punctuation">></span></span>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}-%line - %m%n<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>pattern</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>charset</span><span class="token punctuation">></span></span>UTF-8<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>charset</span><span class="token punctuation">></span></span> <span class="token comment"><!-- 此处设置字符集 --></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>encoder</span><span class="token punctuation">></span></span> <span class="token comment"><!-- 日志记录器的滚动策略,按日期,按大小记录 --></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>rollingPolicy</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>ch.qos.logback.core.rolling.TimeBasedRollingPolicy<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>fileNamePattern</span><span class="token punctuation">></span></span>${logger.path}/error/log-error-%d{yyyy-MM-dd}.%i.log<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>fileNamePattern</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>timeBasedFileNamingAndTriggeringPolicy</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>maxFileSize</span><span class="token punctuation">></span></span>100MB<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>maxFileSize</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>timeBasedFileNamingAndTriggeringPolicy</span><span class="token punctuation">></span></span> <span class="token comment"><!--日志文件保留天数--></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>maxHistory</span><span class="token punctuation">></span></span>15<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>maxHistory</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>rollingPolicy</span><span class="token punctuation">></span></span> <span class="token comment"><!-- 此日志文件只记录ERROR级别的 --></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>filter</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>ch.qos.logback.classic.filter.LevelFilter<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>level</span><span class="token punctuation">></span></span>ERROR<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>level</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>onMatch</span><span class="token punctuation">></span></span>ACCEPT<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>onMatch</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>onMismatch</span><span class="token punctuation">></span></span>DENY<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>onMismatch</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>filter</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>appender</span><span class="token punctuation">></span></span> <span class="token comment"><!-- root节点是必选节点,用来指定最基础的日志输出级别,只有一个level属性 level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF, 不能设置为INHERITED或者同义词NULL。默认是DEBUG 可以包含零个或多个元素,标识这个appender将会添加到这个logger。 --></span> <span class="token comment"><!-- 打印sql,但不打印事务等 com.bank.mapper为我自己mapper存放的包名--></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>logger</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>com.bank.mapper<span class="token punctuation">"</span></span> <span class="token attr-name">level</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>DEBUG<span class="token punctuation">"</span></span> <span class="token attr-name">additivity</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>false<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>appender-ref</span> <span class="token attr-name">ref</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>CONSOLE<span class="token punctuation">"</span></span><span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>appender-ref</span> <span class="token attr-name">ref</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>DEBUG_FILE<span class="token punctuation">"</span></span><span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>logger</span><span class="token punctuation">></span></span> <span class="token comment"><!-- 打印事务、mapper注册等信息,打印到控制台、记录到debug_file --></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>logger</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>org.mybatis.spring.SqlSessionUtils<span class="token punctuation">"</span></span> <span class="token attr-name">level</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>DEBUG<span class="token punctuation">"</span></span> <span class="token attr-name">additivity</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>false<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>appender-ref</span> <span class="token attr-name">ref</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>CONSOLE<span class="token punctuation">"</span></span><span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>appender-ref</span> <span class="token attr-name">ref</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>DEBUG_FILE<span class="token punctuation">"</span></span><span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>logger</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>root</span> <span class="token attr-name">level</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>info<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>appender-ref</span> <span class="token attr-name">ref</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>CONSOLE<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>appender-ref</span> <span class="token attr-name">ref</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>DEBUG_FILE<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>appender-ref</span> <span class="token attr-name">ref</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>INFO_FILE<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>appender-ref</span> <span class="token attr-name">ref</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>WARN_FILE<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>appender-ref</span> <span class="token attr-name">ref</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>ERROR_FILE<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>root</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>configuration</span><span class="token punctuation">></span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre></code></pre></details><ol><li>把业务日志代码记录到info级别的log中,即配置中的log_info.log;sql日志和事务日志记录到debug级别中,即log_debug.log。通过两个不同的appender实现。</li><li>MyBatis-Plus的配置中默认支持打印日志到控制台或者输出到日志文件,但不能同时支持,要么只在控制台打印,要么只输出到日志文件。默认配置即可能以下配置实现:</li></ol><pre class="line-numbers language-none"><code class="language-none">mybatis-plus: configuration: logImpl: org.apache.ibatis.logging.slf4j.Slf4jImpl # 默认输出到日志文件 logImpl: org.apache.ibatis.logging.stdout.StdOutImpl #默认输出到控制台<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre><p>如果严格区分环境,一般是不需要同时输出的。</p><p>解决方式,通过logback配置处理</p><ul><li>a) 控制台的appender的filter level为debug,因为mybatis代码中事务打印和sql打印都是debug级别;</li><li>b)指定<code><logger></code>配置。<pre class="line-numbers language-none"><code class="language-none"><logger name="com.bank.mapper" level="DEBUG"> <appender-ref ref="CONSOLE"/> <appender-ref ref="DEBUG_FILE"/> </logger> <!-- 打印事务、mapper注册等信息,打印到控制台、记录到debug_file --> <logger name="org.mybatis.spring.SqlSessionUtils" level="DEBUG"> <appender-ref ref="CONSOLE"/> <appender-ref ref="DEBUG_FILE"/> </logger><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>其中<code>org.mybatis.spring.SqlSessionUtils</code>是事务开启、关闭的日志打印类,如果还需打印mapper的注册信息等,可以按package打印<code>org.mybatis.spring</code>。以下为事务打印的实现方法,可以看出都是debug级别的<pre class="line-numbers language-none"><code class="language-none">if (environment.getTransactionFactory() instanceof SpringManagedTransactionFactory) { LOGGER.debug(() -> "Registering transaction synchronization for SqlSession [" + session + "]"); holder = new SqlSessionHolder(session, executorType, exceptionTranslator); TransactionSynchronizationManager.bindResource(sessionFactory, holder); TransactionSynchronizationManager .registerSynchronization(new SqlSessionSynchronization(holder, sessionFactory)); holder.setSynchronizedWithTransaction(true); holder.requested(); } else { if (TransactionSynchronizationManager.getResource(environment.getDataSource()) == null) { LOGGER.debug(() -> "SqlSession [" + session + "] was not registered for synchronization because DataSource is not transactional"); } else { throw new TransientDataAccessResourceException( "SqlSessionFactory must be using a SpringManagedTransactionFactory in order to use Spring transaction synchronization"); } } } else { LOGGER.debug(() -> "SqlSession [" + session + "] was not registered for synchronization because synchronization is not active"); }<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre></li></ul><ol start="3"><li><p>关于sql日志和业务日志分成不同文件,日志查看连贯性受影响,可以通过MDC处理,见我另一篇文件<a href="https://everspring.github.io/2022/08/23/mdc-xiang-jie/">MDC在多线程中的使用</a>,写好MDC实现后,在日志中配置好即可。<br>也可引用轻量日志组件<a href="https://gitee.com/dromara/TLog.git">TLog</a>,就可以不用再自己实现MDC,参考文章:<a href="https://tlog.yomahub.com/pages/eea781/">TLog MDC模式下logback的配置</a></p></li><li><p>Logback的<code><appender></code>+<code><logger></code>可以很好的解决按照不同模块记录日志。有两种方式:</p></li></ol><ul><li>a) 工程按照业务模块划分成了不同package,可以通过<code><appender></code>+<code><logger name="包名"></code>组合实现,此方式不需要修改java代码;</li><li>b) 如果不能按照package划分,就需要通过代码中<code>Logger LOGGER = LoggerFactory.getLogger("logger name的值");</code>来指定(如用了Lombok,可用<code>@Slf4j(topic="logger name的值")</code>)<pre class="line-numbers language-xml" data-language="xml"><code class="language-xml"><span class="token comment"><!-- 时间滚动输出 level为 pbc模块INFO 日志 --></span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>appender</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>user_module_appender<span class="token punctuation">"</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>ch.qos.logback.core.rolling.RollingFileAppender<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token comment"><!-- 正在记录的日志文件的路径及文件名 --></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>file</span><span class="token punctuation">></span></span>${logger.path}/pbc_log_info.log<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>file</span><span class="token punctuation">></span></span> <span class="token comment"><!--日志文件输出格式--></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>encoder</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>pattern</span><span class="token punctuation">></span></span>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %C.%M-%line - %m%n<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>pattern</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>charset</span><span class="token punctuation">></span></span>UTF-8<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>charset</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>encoder</span><span class="token punctuation">></span></span> <span class="token comment"><!-- 日志记录器的滚动策略,按日期,按大小记录 --></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>rollingPolicy</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>ch.qos.logback.core.rolling.TimeBasedRollingPolicy<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token comment"><!-- 每天日志归档路径以及格式 --></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>fileNamePattern</span><span class="token punctuation">></span></span>${logger.path}/info/pbc_log-info-%d{yyyy-MM-dd}.%i.log<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>fileNamePattern</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>timeBasedFileNamingAndTriggeringPolicy</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>maxFileSize</span><span class="token punctuation">></span></span>100MB<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>maxFileSize</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>timeBasedFileNamingAndTriggeringPolicy</span><span class="token punctuation">></span></span> <span class="token comment"><!--日志文件保留天数--></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>maxHistory</span><span class="token punctuation">></span></span>15<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>maxHistory</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>rollingPolicy</span><span class="token punctuation">></span></span> <span class="token comment"><!-- 此日志文件只记录info级别的 --></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>filter</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>ch.qos.logback.classic.filter.LevelFilter<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>level</span><span class="token punctuation">></span></span>info<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>level</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>onMatch</span><span class="token punctuation">></span></span>ACCEPT<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>onMatch</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>onMismatch</span><span class="token punctuation">></span></span>DENY<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>onMismatch</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>filter</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>appender</span><span class="token punctuation">></span></span><span class="token comment"><!-- 业务模块 --></span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>logger</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>user_module_logger<span class="token punctuation">"</span></span> <span class="token attr-name">level</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>info<span class="token punctuation">"</span></span> <span class="token attr-name">additivity</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>false<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>appender-ref</span> <span class="token attr-name">ref</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>user_module_appender<span class="token punctuation">"</span></span><span class="token punctuation">/></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>logger</span><span class="token punctuation">></span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre></li></ul><p><strong>注意:</strong>如果用了代码方式匹配logger name,日志可能打印出来没有类、方法信息,打印出的是<code>user_module_logger</code>,因为很多时候encoder配置的是%logger,而%logger会被logger name替换。如要打印出类、方法信息,%logger应改为%C.%M,%C代表class,%M代表方法,具体的变量可见<code>ch.qos.logback.classic.PatternLayout</code>类</p><pre class="line-numbers language-java" data-language="java"><code class="language-java">DEFAULT_CONVERTER_MAP<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">"lo"</span><span class="token punctuation">,</span> <span class="token class-name">LoggerConverter</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">.</span><span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>DEFAULT_CONVERTER_MAP<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">"logger"</span><span class="token punctuation">,</span> <span class="token class-name">LoggerConverter</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">.</span><span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>DEFAULT_CONVERTER_MAP<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">"c"</span><span class="token punctuation">,</span> <span class="token class-name">LoggerConverter</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">.</span><span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>DEFAULT_CONVERTER_MAP<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">"C"</span><span class="token punctuation">,</span> <span class="token class-name">ClassOfCallerConverter</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">.</span><span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>DEFAULT_CONVERTER_MAP<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">"class"</span><span class="token punctuation">,</span> <span class="token class-name">ClassOfCallerConverter</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">.</span><span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>CONVERTER_CLASS_TO_KEY_MAP<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token class-name">ClassOfCallerConverter</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">.</span><span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"class"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>DEFAULT_CONVERTER_MAP<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">"M"</span><span class="token punctuation">,</span> <span class="token class-name">MethodOfCallerConverter</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">.</span><span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>DEFAULT_CONVERTER_MAP<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">"method"</span><span class="token punctuation">,</span> <span class="token class-name">MethodOfCallerConverter</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">.</span><span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>CONVERTER_CLASS_TO_KEY_MAP<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token class-name">MethodOfCallerConverter</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">.</span><span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"method"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>]]></content>
<categories>
<category> JAVA </category>
</categories>
<tags>
<tag> 日志 </tag>
</tags>
</entry>
<entry>
<title>MDC在多线程中的使用</title>
<link href="/2022/08/23/mdc-xiang-jie/"/>
<url>/2022/08/23/mdc-xiang-jie/</url>
<content type="html"><![CDATA[<h1 id="一、了解MDC"><a href="#一、了解MDC" class="headerlink" title="一、了解MDC"></a>一、了解MDC</h1><p>MDC(Mapped Diagnostic Context,映射调试上下文)是 slf4j提供的一种轻量级的日志跟踪工具。Log4j、Logback或者Log4j2等日志中最常见区分同一个请求的方式是通过线程名,而如果<br>请求量大,线程名在相近的时间内会有很多重复的而无法分辨,因此引出了trace-id,即在接收到的时候生成唯一的请求id,在整个执行链路中带上此唯一id.<br>MDC.java本身不提供传递traceId的能力,真正提供能力的是<code>MDCAdapter</code>接口的实现。比如Log4j的是<code>Log4jMDCAdapter</code>,Logback的是<code>LogbackMDCAdapter</code>。</p><h1 id="二、MDC普通使用"><a href="#二、MDC普通使用" class="headerlink" title="二、MDC普通使用"></a>二、MDC普通使用</h1><ol><li>MDC.put(“trace-id”, traceId); // 添加traceId</li><li>MDC.remove(“trace-id”); // 移除traceId</li><li>在日志配置文件中<code><pattern></code>节点中以<code>%X{trace-id}</code>取出,比如:<code><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level [uniqid-%X{trace-id}] %logger{50}-%line - %m%n</pattern></code><br>以上方式,只能在做put操作的当前线程中获取到值。那是因为MDC的实现原理主要就是ThreadLocal,ThreadLocal只对当前线程有效。</li></ol><h1 id="三、多线程中的MDC"><a href="#三、多线程中的MDC" class="headerlink" title="三、多线程中的MDC"></a>三、多线程中的MDC</h1><p>要破除ThreadLocal只对当前线程有线的方法有两种:<br>一种是JDK自带的、ThreadLocal的扩展类<code>InheritableThreadLocal</code>,子线程会拷贝父线程中的变量值<br>一种是引入alibaba<code>transmittable-thread-local</code>包的<code>TransmittableThreadLocal</code>实现 </p><blockquote><p>据我所知,只有子线程获取父线程,不能父线程获取子线程的变量,如果有知道父获取子的方法,麻烦说一下,谢谢</p></blockquote><p>Sl4j本身的提供的<code>BasicMDCAdapter</code>就是基于<code>InheritableThreadLocal</code>实现了线程间传递,但log4j、logback这两个实际的日志实现没有提供,log4j2提供了但默认关闭。</p><ol><li>log4j2主要是根据<code>isThreadContextMapInheritable</code>变量控制的,有两种方法:<ul><li>log4j2.component.properties文件中配置</li><li>类型模块中定义,<code>System.setProperty("log4j2.isThreadContextMapInherimeble", "true");</code></li></ul></li><li>lob4j和logback需要自己手动实现,主要有两种方法,一是<code>手动在线程中的处理</code>,一种是重写<code>LogbackMDCAdapter</code>。本文以在线程池中创建为例<pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>slf4j<span class="token punctuation">.</span></span>MDC<span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>util<span class="token punctuation">.</span></span><span class="token class-name">CollectionUtils</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">java<span class="token punctuation">.</span>util<span class="token punctuation">.</span></span><span class="token class-name">Map</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">java<span class="token punctuation">.</span>util<span class="token punctuation">.</span>concurrent<span class="token punctuation">.</span></span><span class="token class-name">Callable</span><span class="token punctuation">;</span><span class="token comment">/** * @desc: 定义MDC工具类,支持Runnable和Callable两种,目的就是为了把父线程的traceId设置给子线程 */</span><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MdcUtil</span> <span class="token punctuation">{</span> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token generics"><span class="token punctuation"><</span><span class="token class-name">T</span><span class="token punctuation">></span></span> <span class="token class-name">Callable</span><span class="token generics"><span class="token punctuation"><</span><span class="token class-name">T</span><span class="token punctuation">></span></span> <span class="token function">wrap</span><span class="token punctuation">(</span><span class="token keyword">final</span> <span class="token class-name">Callable</span><span class="token generics"><span class="token punctuation"><</span><span class="token class-name">T</span><span class="token punctuation">></span></span> callable<span class="token punctuation">,</span> <span class="token keyword">final</span> <span class="token class-name">Map</span><span class="token generics"><span class="token punctuation"><</span><span class="token class-name">String</span><span class="token punctuation">,</span> <span class="token class-name">String</span><span class="token punctuation">></span></span> context<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-></span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token class-name">CollectionUtils</span><span class="token punctuation">.</span><span class="token function">isEmpty</span><span class="token punctuation">(</span>context<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> MDC<span class="token punctuation">.</span><span class="token function">clear</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> MDC<span class="token punctuation">.</span><span class="token function">setContextMap</span><span class="token punctuation">(</span>context<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">try</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> callable<span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">finally</span> <span class="token punctuation">{</span> <span class="token comment">// 清除子线程的,避免内存溢出,就和ThreadLocal.remove()一个原因</span> MDC<span class="token punctuation">.</span><span class="token function">clear</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token class-name">Runnable</span> <span class="token function">wrap</span><span class="token punctuation">(</span><span class="token keyword">final</span> <span class="token class-name">Runnable</span> runnable<span class="token punctuation">,</span> <span class="token keyword">final</span> <span class="token class-name">Map</span><span class="token generics"><span class="token punctuation"><</span><span class="token class-name">String</span><span class="token punctuation">,</span> <span class="token class-name">String</span><span class="token punctuation">></span></span> context<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-></span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token class-name">CollectionUtils</span><span class="token punctuation">.</span><span class="token function">isEmpty</span><span class="token punctuation">(</span>context<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> MDC<span class="token punctuation">.</span><span class="token function">clear</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> MDC<span class="token punctuation">.</span><span class="token function">setContextMap</span><span class="token punctuation">(</span>context<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">try</span> <span class="token punctuation">{</span> runnable<span class="token punctuation">.</span><span class="token function">run</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">finally</span> <span class="token punctuation">{</span> MDC<span class="token punctuation">.</span><span class="token function">clear</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">import</span> <span class="token namespace">java<span class="token punctuation">.</span>util<span class="token punctuation">.</span>concurrent<span class="token punctuation">.</span></span><span class="token class-name">Callable</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">java<span class="token punctuation">.</span>util<span class="token punctuation">.</span>concurrent<span class="token punctuation">.</span></span><span class="token class-name">Future</span><span class="token punctuation">;</span><span class="token comment">/** * @desc: 把当前的traceId透传到子线程特意加的实现。重点就是 MDC.getCopyOfContextMap(),此方法获取当前线程(父线程)的traceId */</span><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">ThreadPoolMdcExecutor</span> <span class="token keyword">extends</span> <span class="token class-name">ThreadPoolTaskExecutor</span> <span class="token punctuation">{</span> <span class="token annotation punctuation">@Override</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">execute</span><span class="token punctuation">(</span><span class="token class-name">Runnable</span> task<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">super</span><span class="token punctuation">.</span><span class="token function">execute</span><span class="token punctuation">(</span><span class="token class-name">MdcUtil</span><span class="token punctuation">.</span><span class="token function">wrap</span><span class="token punctuation">(</span>task<span class="token punctuation">,</span> MDC<span class="token punctuation">.</span><span class="token function">getCopyOfContextMap</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token annotation punctuation">@Override</span> <span class="token keyword">public</span> <span class="token class-name">Future</span><span class="token generics"><span class="token punctuation"><</span><span class="token operator">?</span><span class="token punctuation">></span></span> <span class="token function">submit</span><span class="token punctuation">(</span><span class="token class-name">Runnable</span> task<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">super</span><span class="token punctuation">.</span><span class="token function">submit</span><span class="token punctuation">(</span><span class="token class-name">MdcUtil</span><span class="token punctuation">.</span><span class="token function">wrap</span><span class="token punctuation">(</span>task<span class="token punctuation">,</span> MDC<span class="token punctuation">.</span><span class="token function">getCopyOfContextMap</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token annotation punctuation">@Override</span> <span class="token keyword">public</span> <span class="token generics"><span class="token punctuation"><</span><span class="token class-name">T</span><span class="token punctuation">></span></span> <span class="token class-name">Future</span><span class="token generics"><span class="token punctuation"><</span><span class="token class-name">T</span><span class="token punctuation">></span></span> <span class="token function">submit</span><span class="token punctuation">(</span><span class="token class-name">Callable</span><span class="token generics"><span class="token punctuation"><</span><span class="token class-name">T</span><span class="token punctuation">></span></span> task<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">super</span><span class="token punctuation">.</span><span class="token function">submit</span><span class="token punctuation">(</span><span class="token class-name">MdcUtil</span><span class="token punctuation">.</span><span class="token function">wrap</span><span class="token punctuation">(</span>task<span class="token punctuation">,</span> MDC<span class="token punctuation">.</span><span class="token function">getCopyOfContextMap</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre></li></ol><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>boot<span class="token punctuation">.</span>autoconfigure<span class="token punctuation">.</span>condition<span class="token punctuation">.</span></span><span class="token class-name">ConditionalOnProperty</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>context<span class="token punctuation">.</span>annotation<span class="token punctuation">.</span></span><span class="token class-name">Bean</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>context<span class="token punctuation">.</span>annotation<span class="token punctuation">.</span></span><span class="token class-name">Configuration</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>scheduling<span class="token punctuation">.</span>concurrent<span class="token punctuation">.</span></span><span class="token class-name">ThreadPoolTaskExecutor</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">javax<span class="token punctuation">.</span>annotation<span class="token punctuation">.</span></span><span class="token class-name">Resource</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">java<span class="token punctuation">.</span>util<span class="token punctuation">.</span>concurrent<span class="token punctuation">.</span></span><span class="token class-name">RejectedExecutionHandler</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">java<span class="token punctuation">.</span>util<span class="token punctuation">.</span>concurrent<span class="token punctuation">.</span></span><span class="token class-name">ScheduledExecutorService</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">java<span class="token punctuation">.</span>util<span class="token punctuation">.</span>concurrent<span class="token punctuation">.</span></span><span class="token class-name">ScheduledThreadPoolExecutor</span><span class="token punctuation">;</span><span class="token comment">/** * 线程池配置。重点就是把ThreadPoolTaskExecutor换成ThreadPoolMdcExecutor **/</span><span class="token annotation punctuation">@Configuration</span><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">ThreadPoolConfig</span> <span class="token punctuation">{</span> <span class="token annotation punctuation">@Resource</span> <span class="token keyword">private</span> <span class="token class-name">ThreadPoolProperties</span> threadPoolProperties<span class="token punctuation">;</span> <span class="token comment">/** * 业务用到的线程池 * @return */</span> <span class="token annotation punctuation">@Bean</span><span class="token punctuation">(</span>name <span class="token operator">=</span> <span class="token string">"threadPoolTaskExecutor"</span><span class="token punctuation">)</span> <span class="token keyword">public</span> <span class="token class-name">ThreadPoolTaskExecutor</span> <span class="token function">threadPoolTaskExecutor</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token class-name">ThreadPoolTaskExecutor</span> executor <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ThreadPoolMdcExecutor</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> executor<span class="token punctuation">.</span><span class="token function">setMaxPoolSize</span><span class="token punctuation">(</span>threadPoolProperties<span class="token punctuation">.</span><span class="token function">getMaxPoolSize</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> executor<span class="token punctuation">.</span><span class="token function">setCorePoolSize</span><span class="token punctuation">(</span>threadPoolProperties<span class="token punctuation">.</span><span class="token function">getCorePoolSize</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> executor<span class="token punctuation">.</span><span class="token function">setQueueCapacity</span><span class="token punctuation">(</span>threadPoolProperties<span class="token punctuation">.</span><span class="token function">getQueueCapacity</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> executor<span class="token punctuation">.</span><span class="token function">setKeepAliveSeconds</span><span class="token punctuation">(</span>threadPoolProperties<span class="token punctuation">.</span><span class="token function">getKeepAliveSeconds</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">RejectedExecutionHandler</span> handler <span class="token operator">=</span> <span class="token class-name">ReflectUtil</span><span class="token punctuation">.</span><span class="token function">newInstance</span><span class="token punctuation">(</span>threadPoolProperties<span class="token punctuation">.</span><span class="token function">getRejectedExecutionHandler</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getClazz</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> executor<span class="token punctuation">.</span><span class="token function">setRejectedExecutionHandler</span><span class="token punctuation">(</span>handler<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> executor<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>推荐文章:</p><ol><li><a href="https://www.cnblogs.com/yangyongjie/p/12523567.html">https://www.cnblogs.com/yangyongjie/p/12523567.html</a></li><li><a href="https://blog.csdn.net/zlt2000/article/details/99641821">https://blog.csdn.net/zlt2000/article/details/99641821</a></li></ol>]]></content>
<categories>
<category> JAVA </category>
</categories>
<tags>
<tag> MDC </tag>
<tag> 多线程日志 </tag>
</tags>
</entry>
<entry>
<title>后端JAVA开发规范</title>
<link href="/2022/08/14/hou-duan-java-kai-fa-gui-fan/"/>
<url>/2022/08/14/hou-duan-java-kai-fa-gui-fan/</url>
<content type="html"><![CDATA[<p>根据原公司规范、阿里巴巴JAVA规范形成</p><h2 id="后端JAVA开发规范"><a href="#后端JAVA开发规范" class="headerlink" title="后端JAVA开发规范"></a>后端JAVA开发规范</h2><p>JAVA开发规范一节借鉴了《阿里巴巴JAVA开发手册》,根据公司情况做了一些删减、补充,建议大家在网上下载《阿里巴巴JAVA开发手册》当前最新版本为嵩山版(截止2022.1.18)仔细阅读,官方地址:<a href="https://github.com/alibaba/p3c">https://github.com/alibaba/p3c</a><br>建议大家安装代码检查工具,比如:Alibaba Java Coding Guidelines、SpotBugs、SonarLint等,开发完成后做代码扫描</p><h4 id="一、-命名"><a href="#一、-命名" class="headerlink" title="一、 命名"></a>一、 命名</h4><ol><li>【强制】类名使用 UpperCamelCase 风格,但以下情形例外:DO / BO / DTO / VO / AO / PO / UID 等<br>正例:ForceCode / UserDO / HtmlDTO / XmlService / TcpUdpDeal / TaPromotion<br>反例:forcecode / UserDo / HTMLDto / XMLService / TCPUDPDeal / TAPromotion</li><li>【强制】方法名、参数名、成员变量、局部变量都统一使用 lowerCamelCase 风格。<br>正例: localValue / getHttpMessage() / inputUserId</li><li>【强制】常量命名全部大写,单词间用下划线隔开,力求语义表达完整清楚,不要嫌名字长。<br>正例:MAX_STOCK_COUNT / CACHE_EXPIRED_TIME<br>反例:MAX_COUNT / EXPIRED_TIME</li><li>【强制】抽象类命名使用 Abstract 或 Base 开头;异常类命名使用 Exception 结尾;测试类命名以它要测试的类的名称开始,以 Test 结尾</li><li>【强制】类型与中括号紧挨相连来表示数组。<br>正例:定义整形数组 int[] arrayDemo。<br>反例:在 main 参数中,使用 String args[]来定义</li><li>【强制】POJO 类中的任何布尔类型的变量,都不要加 is 前缀,否则部分框架解析会引起序列化错误</li><li>【强制】包名统一使用小写,点分隔符之间有且仅有一个自然语义的英语单词。包名统一使用单数形式,但是类名如果有复数含义,类名可以使用复数形式<br>正例:应用工具类包名为 com.alibaba.ei.kunlun.aap.util、类名为 MessageUtils(此规则参考 spring 的框架结构)</li><li>【强制】避免在子父类的成员变量之间、或者不同代码块的局部变量之间采用完全相同的命名,使可理解性降低。说明:子类、父类成员变量名相同,即使是 public 类型的变量也能够通过编译,另外,局部变量在同一方法内的不同代码块中同名也是合法的,这些情况都要避免。对于非 setter/getter 的参数名称也要避免与成员变量名称相同。</li><li>【参考】枚举类名带上 Enum 后缀,枚举成员名称需要全大写,单词间用下划线隔开<br>说明:枚举其实就是特殊的常量类,且构造方法被默认强制是私有<br>正例:枚举名字为 ProcessStatusEnum 的成员名称:SUCCESS / UNKNOWN_REASON</li></ol><h4 id="二、-OOP规约"><a href="#二、-OOP规约" class="headerlink" title="二、 OOP规约"></a>二、 OOP规约</h4><ol><li>【强制】避免通过一个类的对象引用访问此类的静态变量或静态方法,无谓增加编译器解析成本,直接用类名来访问即可</li><li>【强制】所有的覆写方法,必须加@Override 注解<br>说明:getObject()与 get0bject()的问题。一个是字母的 O,一个是数字的 0,加@Override 可以准确判断是否覆盖成功。另外,如果在抽象类中对方法签名进行修改,其实现类会马上编译报错</li><li>【强制】相同参数类型,相同业务含义,才可以使用 Java 的可变参数,避免使用 Object<br>说明:可变参数必须放置在参数列表的最后(建议开发者尽量不用可变参数编程)<br>正例:public List<User> listUsers(String type, Long… ids) {…}</li><li>【强制】Object 的 equals 方法容易抛空指针异常,应使用常量或确定有值的对象来调用 equals<br>正例:”test”.equals(object)<br>反例:object.equals(“test”);<br>说明:推荐使用 JDK7 引入的工具类 java.util.Objects#equals(Object a, Object b)</li><li>【强制】所有整型包装类对象之间值的比较,全部使用 equals 方法比较</li><li>【强制】任何货币金额,均以最小货币单位且整型类型来进行存</li><li>【强制】浮点数之间的等值判断,基本数据类型不能用==来比较,包装数据类型不能用 equals来判断</li><li>【强制】浮点数之间的等值判断,基本数据类型不能用==来比较,包装数据类型不能用 equals来判断<br>说明:equals()方法会比较值和精度(1.0 与 1.00 返回结果为 false),而 compareTo()则会忽略精度</li><li>【强制】定义数据对象 DO 类时,属性类型要与数据库字段类型相匹配<br>正例:数据库字段的 bigint 必须与类属性的 Long 类型相对应<br>反例:某个案例的数据库表 id 字段定义类型 bigint unsigned,实际类对象属性为 Integer,随着 id 越来越大,超过 Integer 的表示范围而溢出成为负数</li><li>【强制】禁止使用构造方法 BigDecimal(double)的方式把 double 值转化为 BigDecimal 对象<br>说明:BigDecimal(double)存在精度损失风险,在精确计算或值比较的场景中可能会导致业务逻辑异常。<br>如:BigDecimal g = new BigDecimal(0.1F); 实际的存储值为:0.10000000149<br>正例:优先推荐入参为 String 的构造方法,或使用 BigDecimal 的 valueOf 方法,此方法内部其实执行了Double 的 toString,而 Double 的 toString 按 double 的实际能表达的精度对尾数进行了截断。<pre class="line-numbers language-none"><code class="language-none">BigDecimal recommend1 = new BigDecimal("0.1");BigDecimal recommend2 = BigDecimal.valueOf(0.1);<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre></li><li>关于基本数据类型与包装数据类型的使用标准如下<ul><li>【强制】所有的 POJO 类属性必须使用包装数据类型</li><li>【强制】RPC 方法的返回值和参数必须使用包装数据类型<br>正例:数据库的查询结果可能是 null,因为自动拆箱,用基本数据类型接收有 NPE 风险</li></ul></li><li>【强制】序列化类新增属性时,请不要修改 serialVersionUID 字段,避免反序列失败;如果完全不兼容升级,避免反序列化混乱,那么请修改 serialVersionUID 值。<br>说明:注意 serialVersionUID 不一致会抛出序列化运行时异常</li><li>【强制】构造方法里面禁止加入任何业务逻辑,如果有初始化逻辑,请放在 init 方法中</li><li>【强制】禁止在 POJO 类中,同时存在对应属性 xxx 的 isXxx()和 getXxx()方法<br>说明:框架在调用属性 xxx 的提取方法时,并不能确定哪个方法一定是被优先调用到的</li><li>【推荐】使用索引访问用 String 的 split 方法得到的数组时,需做最后一个分隔符后有无内容的检查,否则会有抛 IndexOutOfBoundsException 的风险</li><li>【推荐】慎用 Object 的 clone 方法来拷贝对象<br>说明:对象 clone 方法默认是浅拷贝,若想实现深拷贝,需覆写 clone 方法实现域对象的深度遍历式拷贝</li></ol><h4 id="三、日期时间"><a href="#三、日期时间" class="headerlink" title="三、日期时间"></a>三、日期时间</h4><ol><li>【强制】日期格式化时,传入 pattern 中表示年份统一使用小写的 y<br>说明:日期格式化时,yyyy 表示当天所在的年,而大写的 YYYY 代表是 week in which year(JDK7 之后 引入的概念),意思是当天所在的周属于的年份,一周从周日开始,周六结束,只要本周跨年,返回的 YYYY 就是下一年</li><li>【强制】获取当前毫秒数:System.currentTimeMillis(); 而不是 new Date().getTime()</li><li>【强制】不允许在程序任何地方中使用:1)java.sql.Date。 2)java.sql.Time;3)java.sql.Timestamp<br>说明:第 1 个不记录时间,getHours()抛出异常;第 2 个不记录日期,getYear()抛出异常;第 3 个在构造方法 super((time/1000)*1000),在 Timestamp 属性 fastTime 和 nanos 分别存储秒和纳秒信息</li><li>【强制】不要在程序中写死一年为 365 天,避免在公历闰年时出现日期转换错误或程序逻辑<br>错误</li></ol><h4 id="四、集合处理"><a href="#四、集合处理" class="headerlink" title="四、集合处理"></a>四、集合处理</h4><ol><li>【强制】关于 hashCode 和 equals 的处理,遵循如下规则:<br>1) 只要覆写 equals,就必须覆写 hashCode。<br>2) 因为 Set 存储的是不重复的对象,依据 hashCode 和 equals 进行判断,所以 Set 存储的对象必须覆写这两种方法<br>3) 如果自定义对象作为 Map 的键,那么必须覆写 hashCode 和 equals</li><li>【强制】判断所有集合内部的元素是否为空,使用 isEmpty()方法,而不是 size()==0 的方式</li><li>【强制】在使用 java.util.stream.Collectors 类的 toMap()方法转为 Map 集合时,一定要使用含有参数类型为 BinaryOperator,参数名为 mergeFunction 的方法,否则当出现相同 key值时会抛出 IllegalStateException 异常。<br>说明:JDK1.8后的版本</li><li>【强制】在使用 java.util.stream.Collectors 类的 toMap()方法转为 Map 集合时,一定要注意当 value 为 null 时会抛 NPE 异常</li><li>【强制】ArrayList 的 subList 结果不可强转成 ArrayList,否则会抛出 ClassCastException 异常:java.util.RandomAccessSubList cannot be cast to java.util.ArrayList。说明:subList()返回的是 ArrayList 的内部类 SubList,并不是 ArrayList 本身,而是 ArrayList 的一个视图,对于 SubList 的所有操作最终会反映到原列表上</li><li>【强制】使用 Map 的方法 keySet()/values()/entrySet()返回集合对象时,不可以对其进行添加元素操作,否则会抛出 UnsupportedOperationException 异常</li><li>【强制】Collections 类返回的对象,如:emptyList()/singletonList()等都是 immutable list,不可对其进行添加或者删除元素的操作</li><li>【强制】在 subList 场景中,高度注意对父集合元素的增加或删除,均会导致子列表的遍历、<br>增加、删除产生 ConcurrentModificationException 异常</li><li>【强制】使用集合转数组的方法,必须使用集合的 toArray(T[] array),传入的是类型完全一致、长度为 0 的空数组<br>反例:直接使用 toArray 无参方法存在问题,此方法返回值只能是 Object[]类,若强转其它类型数组将出现ClassCastException 错误</li><li>【强制】在使用 Collection 接口任何实现类的 addAll()方法时,都要对输入的集合参数进行NPE 判断<br>说明:在 ArrayList#addAll 方法的第一行代码即 Object[] a = c.toArray(); 其中 c 为输入集合参数,如果为 null,则直接抛出异常</li><li>【强制】使用工具类 Arrays.asList()把数组转换成集合时,不能使用其修改集合相关的方法, 它的 add/remove/clear 方法会抛出 UnsupportedOperationException 异常</li><li>【强制】泛型通配符<? extends T>来接收返回的数据,此写法的泛型集合不能使用 add 方法, 而<? super T>不能使用 get 方法,两者在接口调用赋值的场景中容易出错<br>说明:扩展说一下 PECS(Producer Extends Consumer Super)原则:第一、频繁往外读取内容的,适合用<? extends T>。第二、经常往里插入的,适合用<? super T></li><li>【强制】在无泛型限制定义的集合赋值给泛型限制的集合时,在使用集合元素时,需要进行instanceof 判断,避免抛出 ClassCastException 异常</li><li>【强制】不要在 foreach 循环里进行元素的 remove/add 操作。remove 元素请使用 Iterator方式,如果并发操作,需要对 Iterator 对象加锁</li></ol><h4 id="五、并发处理"><a href="#五、并发处理" class="headerlink" title="五、并发处理"></a>五、并发处理</h4><ol><li>【强制】获取单例对象需要保证线程安全,其中的方法也要保证线程安全</li><li>【强制】创建线程或线程池时请指定有意义的线程名称,方便出错时回溯</li><li>【强制】线程资源必须通过线程池提供,不允许在应用中自行显式创建线程<br>说明:线程池的好处是减少在创建和销毁线程上所消耗的时间以及系统资源的开销,解决资源不足的问题。如果不使用线程池,有可能造成系统创建大量同类线程而导致消耗完内存或者“过度切换”的问题</li><li>【强制】SimpleDateFormat 是线程不安全的类,一般不要定义为 static 变量,如果定义为static必须加锁,或者使用 DateUtils 工具类<br>正例:注意线程安全,使用 DateUtils。亦推荐如下处理<pre class="line-numbers language-none"><code class="language-none">private static final ThreadLocal<DateFormat> df = new ThreadLocal<DateFormat>() { @Override protected DateFormat initialValue() { return new SimpleDateFormat("yyyy-MM-dd"); }};<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>说明:如果是 JDK8 的应用,可以使用 Instant 代替 Date,LocalDateTime 代替 Calendar, DateTimeFormatter 代替 SimpleDateFormat,官方给出的解释:simple beautiful strong immutable thread-safe</li><li>【强制】必须回收自定义的 ThreadLocal 变量,尤其在线程池场景下,线程经常会被复用, 如果不清理自定义的 ThreadLocal 变量,可能会影响后续业务逻辑和造成内存泄露等问题。 尽量在代理中使用 try-finally 块进行回收<br>正例:<pre class="line-numbers language-none"><code class="language-none">objectThreadLocal.set(userInfo);try { // ...} finally { objectThreadLocal.remove();}<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre></li><li>【强制】高并发时,同步调用应该去考量锁的性能损耗。能用无锁数据结构,就不要用锁;能 锁区块,就不要锁整个方法体;能用对象锁,就不要用类锁<br>说明:尽可能使加锁的代码块工作量尽可能的小,避免在锁代码块中调用 RPC 方法</li><li>【强制】对多个资源、数据库表、对象同时加锁时,需要保持一致的加锁顺序,否则可能会造成死锁<br>说明:线程一需要对表 A、B、C 依次全部加锁后才可以进行更新操作,那么线程二的加锁顺序也必须是 A、B、C,否则可能出现死锁</li><li>【强制】在使用阻塞等待获取锁的方式中,必须在 try 代码块之外,并且在加锁方法与 try 代 码块之间没有任何可能抛出异常的方法调用,避免加锁成功后,在 finally 中无法解锁。<br>说明一:如果在 lock 方法与 try 代码块之间的方法调用抛出异常,那么无法解锁,造成其它线程无法成功获取锁。<br>说明二:如果 lock 方法在 try 代码块之内,可能由于其它方法抛出异常,导致在 finally 代码块中,unlock对未加锁的对象解锁,它会调用 AQS 的 tryRelease 方法(取决于具体实现类),抛出<br>IllegalMonitorStateException 异常。<br>说明三:在 Lock 对象的 lock 方法实现中可能抛出 unchecked 异常,产生的后果与说明二相同<br>正例:<pre class="line-numbers language-none"><code class="language-none">Lock lock = new XxxLock();// ...lock.lock();try { doSomething(); doOthers();} finally { lock.unlock();}<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>反例:<pre class="line-numbers language-none"><code class="language-none">Lock lock = new XxxLock();try { // 如果此处抛出异常,则直接执行 finally 代码块 doSomething(); // 无论加锁是否成功,finally 代码块都会执行 lock.lock(); doOthers();} finally { lock.unlock();}<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre></li><li>【强制】在使用尝试机制来获取锁的方式中,进入业务代码块之前,必须先判断当前线程是否持有锁。锁的释放规则与锁的阻塞等待方式相同<br>说明:Lock 对象的 unlock 方法在执行时,它会调用 AQS 的 tryRelease 方法(取决于具体实现类),如果 当前线程不持有锁,则抛出 IllegalMonitorStateException 异常<pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token class-name">Lock</span> lock <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">XxxLock</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">// ...</span><span class="token keyword">boolean</span> isLocked <span class="token operator">=</span> lock<span class="token punctuation">.</span><span class="token function">tryLock</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">if</span> <span class="token punctuation">(</span>isLocked<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">try</span> <span class="token punctuation">{</span> <span class="token function">doSomething</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">doOthers</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">finally</span> <span class="token punctuation">{</span> lock<span class="token punctuation">.</span><span class="token function">unlock</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre></li><li>【强制】并发修改同一记录时,避免更新丢失,需要加锁。要么在应用层加锁,要么在缓存加 锁,要么在数据库层使用乐观锁,使用 version 作为更新依据。<br>说明:如果每次访问冲突概率小于 20%,推荐使用乐观锁,否则使用悲观锁。乐观锁的重试次数不得小于3 次。</li><li>【推荐】使用 CountDownLatch 进行异步转同步操作,每个线程退出前必须调用 countDown 方 法,线程执行代码注意 catch 异常,确保 countDown 方法被执行到,避免主线程无法执行至 await 方法,直到超时才返回结果。<br>说明:注意,子线程抛出异常堆栈,不能在主线程 try-catch 到</li><li>【推荐】避免 Random 实例被多线程使用,虽然共享该实例是线程安全的,但会因竞争同一 seed导致的性能下降<br>说明:Random 实例包括 java.util.Random 的实例或者 Math.random()的方式。<br>正例:在 JDK7 之后,可以直接使用 API ThreadLocalRandom,而在 JDK7 之前,需要编码保证每个线程持有一个单独的 Random 实例</li><li>【参考】ThreadLocal 对象使用 static 修饰,ThreadLocal 无法解决共享对象的更新问题</li></ol><h4 id="六、前、后端公约"><a href="#六、前、后端公约" class="headerlink" title="六、前、后端公约"></a>六、前、后端公约</h4><ol><li>【强制】前后端交互的 API,需要明确协议、域名、路径、请求方法、请求内容、状态码、响应体</li><li>【强制】前后端数据<strong>列表</strong>相关的接口返回,如果为空,则返回空数组[]或空集合{}<br>说明:此条约定有利于数据层面上的协作更加高效,减少前端很多琐碎的 null 判断</li><li>【强制】在前后端交互的 JSON 格式数据中,所有的 key 必须为小写字母开始的lowerCamelCase 风格,符合英文表达习惯,且表意完整</li><li>【强制】对于需要使用超大整数的场景,服务端一律使用 String 字符串类型返回,禁止使用Long 类型</li><li>【强制】HTTP 请求通过 URL 传递参数时,不能超过 2048 字节</li><li>【强制】HTTP 请求通过 body 传递内容时,必须控制长度,超出最大长度后,后端解析会出错<br>说明:nginx 默认限制是 1MB,tomcat 默认限制为 2MB,当确实有业务需要传较大内容时,可以通过调大服务器端的限制。<br>Nginx调整参数:client_max_body_size<br>tomcat调整参数:server.xml中的节点添加maxPostSize</li><li>【强制】在翻页场景中,用户输入参数的小于 1,则前端返回第一页参数给后端;后端发现用户输入的参数大于总页数,直接返回最后一页</li><li>【强制】服务器内部重定向必须使用 forward;外部重定向地址必须使用 URL 统一代理模块生成,否则会因线上采用 HTTPS 协议而导致浏览器提示“不安全”,并且还会带来 URL 维护不一致的问题</li><li>【推荐】前后端的时间格式统一为”yyyy-MM-dd HH:mm:ss”,统一为 GMT</li><li>【参考】在接口路径中不要加入版本号,版本控制在 HTTP 头信息中体现,有利于向前兼容</li></ol><h4 id="七、其他"><a href="#七、其他" class="headerlink" title="七、其他"></a>七、其他</h4><ol><li>【强制】finally 块必须对资源对象、流对象进行关闭,有异常也要做 try-catch<br>说明:如果 JDK7 及以上,可以使用 try-with-resources 方式</li><li>【强制】不要在 finally 块中使用 return<br>说明:try 块中的 return 语句执行成功后,并不马上返回,而是继续执行 finally 块中的语句,如果此处存在 return 语句,则在此直接返回,无情丢弃掉 try 块中的返回点</li><li>【强制】应用中不可直接使用日志系统(Log4j、Logback)中的 API,而应依赖使用日志框架(SLF4J、JCL–Jakarta Commons Logging)中的 API,使用门面模式的日志框架,有利于维护和各个类的日志处理方式统一</li><li>【强制】在日志输出时,字符串变量之间的拼接使用占位符的方式<br>说明:因为 String 字符串的拼接会使用 StringBuilder 的 append()方式,有一定的性能损耗。使用占位符仅是替换动作,可以有效提升性能。<br>正例:logger.debug(“Processing trade with id: {} and symbol: {}”, id, symbol);</li><li>【强制】生产环境禁止直接使用 System.out 或 System.err 输出日志或使用e.printStackTrace()打印异常堆栈</li></ol>]]></content>
<categories>
<category> JAVA </category>
</categories>
<tags>
<tag> 规范 </tag>
<tag> Java </tag>
</tags>
</entry>
<entry>
<title>kali系列-一.kali U盘安装</title>
<link href="/2022/04/30/kali-xi-lie-1-kali-an-zhuang/"/>
<url>/2022/04/30/kali-xi-lie-1-kali-an-zhuang/</url>
<content type="html"><![CDATA[<p>kali系统是渗透测试的瑞士军刀,集成了大部分常用的Hack工具。<br>说说U盘安装kali的好处:</p><ol><li>虚拟机安装kali,不支持wifi,如果要支持wifi需要额外使用无线网卡</li><li>不用虚拟机,要么装双系统、要么再准备一台电脑(土豪随意)</li><li>装电脑里不方便携带</li></ol><h3 id="一、前期准备"><a href="#一、前期准备" class="headerlink" title="一、前期准备"></a>一、前期准备</h3><ul><li>U盘<br>建议USB 3.0,2.0比较卡。<br>至少16G,建议32G以上</li><li>DiskGenius U盘分区工具<br>百度找</li><li>Universal-USB-Installer iso系统镜像烧录工具<br>下载地址:<a href="http://downza.51speed.top/2022/02/08/UniversalUSB.rar?timestamp=626cdc34&auth_key=332de8aadceebdf3002d5c208110e680">http://downza.51speed.top/2022/02/08/UniversalUSB.rar?timestamp=626cdc34&auth_key=332de8aadceebdf3002d5c208110e680</a><br>推荐使用,原因:小巧,只有2M左右。<br>不推荐UltraISO,我这烧录后有问题</li><li>kali live iso镜像下载<br>我的是2021.2-live-amd64.iso<br>镜像地址,国外的下载慢,建议用国内的。<br>清华大学镜像:<a href="https://mirrors.tuna.tsinghua.edu.cn/kali-images/">https://mirrors.tuna.tsinghua.edu.cn/kali-images/</a><br>中国科学技术大学:<a href="https://mirrors.ustc.edu.cn/kali-images/">https://mirrors.ustc.edu.cn/kali-images/</a></li></ul><h3 id="二、使用"><a href="#二、使用" class="headerlink" title="二、使用"></a>二、使用</h3><ul><li><strong>1. DiskGenius分区</strong><img src="https://raw.githubusercontent.com/EverSpring/picbed/main/202205082341257.png" alt="图1" style="zoom: 50%;" /><img src="https://raw.githubusercontent.com/EverSpring/picbed/main/202205082341891.png" alt="图2" style="zoom: 50%;" /></li><li><img src="https://raw.githubusercontent.com/EverSpring/picbed/main/202205082342164.png" alt="image-20220430235104169" style="zoom:50%;" /><img src="https://raw.githubusercontent.com/EverSpring/picbed/main/202205082342039.png" alt="image-20220430235741924" style="zoom:50%;" /><img src="https://raw.githubusercontent.com/EverSpring/picbed/main/202205082342428.png" alt="image-20220430235926700" style="zoom:50%;" /></li><li><strong>2. Universal-USB-Installer烧制启动盘</strong></li></ul><img src="https://raw.githubusercontent.com/EverSpring/picbed/main/202205082342833.png" style="zoom: 80%;" /><p>完成后得到了一个可以u盘启动的kali 操作系统,即kali live usb</p><ul><li><p><strong>3. U盘启动</strong><br>在第2步烧制后,重启电脑,进入BIOS系统。进入BIOS系统各品牌的方式,见<a href="https://jingyan.baidu.com/article/cbf0e500b4c71b2eaa2893fd.html">https://jingyan.baidu.com/article/cbf0e500b4c71b2eaa2893fd.html</a></p><img src="https://raw.githubusercontent.com/EverSpring/picbed/main/202205082342387.png" alt="image-20220501000544177" style="zoom: 67%;" /></li></ul><p>进入系统后这两种都可以。下面一种是自动支持持久化的,但持久化的是文件,系统配置持久化暂时还没找到方法</p><blockquote><p>kali 2019后系统的用户是kali,密码也是kali。<br>系统没有提供root用户,但提供了sudo权限,所以后续一些提示权限不足的,就用sudo xxx执行即可</p></blockquote>]]></content>
<categories>
<category> kali </category>
</categories>
<tags>
<tag> 渗透测试 </tag>
<tag> kali U盘安装 </tag>
</tags>
</entry>
<entry>
<title>jackson解析有数组的xml,解析对象不固定的问题</title>
<link href="/2022/04/09/jackson-jie-xi-you-shu-zu-de-xml-jie-xi-dui-xiang-bu-gu-ding-de-wen-ti/"/>
<url>/2022/04/09/jackson-jie-xi-you-shu-zu-de-xml-jie-xi-dui-xiang-bu-gu-ding-de-wen-ti/</url>
<content type="html"><![CDATA[<br/><h1 id="环境"><a href="#环境" class="headerlink" title="环境"></a>环境</h1><p>springboot版本2.2.11.RELEASE,jackson version为<strong>2.10.0</strong> </p><p>以下为第一版样例代码,后面XML不会变,ServiceBusReq类的内容会变:</p><ul><li>请求体</li></ul><pre class="line-numbers language-xml" data-language="xml"><code class="language-xml"><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>TX</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>TX_HEADER</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>SYS_HDR_LEN</span><span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>SYS_PKG_VRSN</span><span class="token punctuation">></span></span>01<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>SYS_PKG_VRSN</span><span class="token punctuation">></span></span>--> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>TX_HEADER</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>TX_EMB</span><span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>ENTITY</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>USER_NAME</span><span class="token punctuation">></span></span>xcc<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>USER_NAME</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>COMPANYS</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>COMPANY</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>COMPANYNAME</span><span class="token punctuation">></span></span>NAME-1<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>COMPANYNAME</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>COMPANY</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>COMPANY</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>COMPANYNAME</span><span class="token punctuation">></span></span>NAME-2<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>COMPANYNAME</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>COMPANY</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>COMPANYS</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>ENTITY</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>TX</span><span class="token punctuation">></span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><ul><li>实体类</li></ul><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token annotation punctuation">@Data</span><span class="token annotation punctuation">@JacksonXmlRootElement</span><span class="token punctuation">(</span>localName <span class="token operator">=</span> <span class="token string">"TX"</span><span class="token punctuation">)</span><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">ServiceBusReq</span><span class="token generics"><span class="token punctuation"><</span><span class="token class-name">T</span><span class="token punctuation">></span></span> <span class="token punctuation">{</span> <span class="token annotation punctuation">@JacksonXmlProperty</span><span class="token punctuation">(</span>localName <span class="token operator">=</span> <span class="token string">"TX_HEADER"</span><span class="token punctuation">)</span> <span class="token keyword">private</span> <span class="token class-name">ServiceBusHeaderReq</span> txHeader<span class="token punctuation">;</span> <span class="token annotation punctuation">@JacksonXmlProperty</span><span class="token punctuation">(</span>localName <span class="token operator">=</span> <span class="token string">"TX_BODY"</span><span class="token punctuation">)</span> <span class="token keyword">private</span> <span class="token class-name">ServiceBusBodyReq</span> txBody<span class="token punctuation">;</span> <span class="token annotation punctuation">@JacksonXmlProperty</span><span class="token punctuation">(</span>localName <span class="token operator">=</span> <span class="token string">"TX_EMB"</span><span class="token punctuation">)</span> <span class="token keyword">private</span> <span class="token class-name">String</span> txEmb<span class="token punctuation">;</span> <span class="token annotation punctuation">@JacksonXmlProperty</span><span class="token punctuation">(</span>localName <span class="token operator">=</span> <span class="token string">"ENTITY"</span><span class="token punctuation">)</span> <span class="token keyword">private</span> <span class="token class-name">T</span> msgObject<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token annotation punctuation">@Data</span><span class="token annotation punctuation">@JacksonXmlRootElement</span><span class="token punctuation">(</span>localName <span class="token operator">=</span> <span class="token string">"TX_HEADER"</span><span class="token punctuation">)</span><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">ServiceBusHeaderReq</span> <span class="token punctuation">{</span> <span class="token annotation punctuation">@JacksonXmlProperty</span><span class="token punctuation">(</span>localName <span class="token operator">=</span> <span class="token string">"SYS_HDR_LEN"</span><span class="token punctuation">)</span> <span class="token keyword">private</span> <span class="token class-name">String</span> sysHdrLen<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token annotation punctuation">@RestController</span><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">ServiceBusController</span> <span class="token punctuation">{</span> <span class="token annotation punctuation">@RequestMapping</span><span class="token punctuation">(</span>method <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token class-name">RequestMethod</span><span class="token punctuation">.</span>POST<span class="token punctuation">}</span><span class="token punctuation">,</span>value <span class="token operator">=</span> <span class="token string">"/service"</span><span class="token punctuation">,</span>consumes <span class="token operator">=</span> <span class="token class-name">MediaType</span><span class="token punctuation">.</span>APPLICATION_XML_VALUE<span class="token punctuation">)</span> <span class="token keyword">public</span> <span class="token class-name">ServiceBusResp</span> <span class="token function">xmlService</span><span class="token punctuation">(</span><span class="token annotation punctuation">@RequestBody</span> <span class="token annotation punctuation">@Valid</span> <span class="token class-name">ServiceBusReq</span> reqDto<span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">ClassNotFoundException</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> serviceBusService<span class="token punctuation">.</span><span class="token function">invoke</span><span class="token punctuation">(</span>reqDto<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token annotation punctuation">@Data</span><span class="token annotation punctuation">@Builder</span><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">XmlDemoReqDto</span> <span class="token punctuation">{</span> <span class="token annotation punctuation">@JacksonXmlProperty</span><span class="token punctuation">(</span>localName <span class="token operator">=</span> <span class="token string">"USER_NAME"</span><span class="token punctuation">)</span> <span class="token keyword">private</span> <span class="token class-name">String</span> <span class="token class-name">UserName</span><span class="token punctuation">;</span> <span class="token annotation punctuation">@JacksonXmlProperty</span><span class="token punctuation">(</span>localName <span class="token operator">=</span> <span class="token string">"COMPANYS"</span><span class="token punctuation">)</span> <span class="token keyword">private</span> <span class="token class-name">List</span><span class="token generics"><span class="token punctuation"><</span><span class="token class-name">Company</span><span class="token punctuation">></span></span> companys<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token annotation punctuation">@Data</span><span class="token annotation punctuation">@JacksonXmlRootElement</span><span class="token punctuation">(</span>localName <span class="token operator">=</span> <span class="token string">"company"</span><span class="token punctuation">)</span><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">Company</span> <span class="token punctuation">{</span> <span class="token annotation punctuation">@JacksonXmlProperty</span><span class="token punctuation">(</span>localName <span class="token operator">=</span> <span class="token string">"COMPANYNAME"</span><span class="token punctuation">)</span> <span class="token keyword">private</span> <span class="token class-name">String</span> companyName<span class="token punctuation">;</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p><strong>ServiceBusReq采用的泛型,反序列化ENTITY的对象是不固定的。XmlDemoReqDto 就是ServiceBusReq的泛型对象</strong></p><h1 id="问题阶段一"><a href="#问题阶段一" class="headerlink" title="问题阶段一"></a>问题阶段一</h1><p>controller中reqDto打印的msgObject类型实际上是一个LinkedHashMap,而LinkedHashMap明显不符合序列化后是个java bean的要求<br><img src="https://github.com/EverSpring/picbed/blob/main/jackson-databaind-1.png" alt="在这里插入图片描述"><br><strong>解决方法:</strong><br>添加一个ObjectNode接收,然后把objectNode再转换成msgObject,代码如下:</p><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token annotation punctuation">@Data</span><span class="token annotation punctuation">@JacksonXmlRootElement</span><span class="token punctuation">(</span>localName <span class="token operator">=</span> <span class="token string">"TX"</span><span class="token punctuation">)</span><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">ServiceBusReq</span><span class="token generics"><span class="token punctuation"><</span><span class="token class-name">T</span><span class="token punctuation">></span></span> <span class="token punctuation">{</span> <span class="token annotation punctuation">@JacksonXmlProperty</span><span class="token punctuation">(</span>localName <span class="token operator">=</span> <span class="token string">"TX_HEADER"</span><span class="token punctuation">)</span> <span class="token keyword">private</span> <span class="token class-name">ServiceBusHeaderReq</span> txHeader<span class="token punctuation">;</span> <span class="token annotation punctuation">@JacksonXmlProperty</span><span class="token punctuation">(</span>localName <span class="token operator">=</span> <span class="token string">"TX_BODY"</span><span class="token punctuation">)</span> <span class="token keyword">private</span> <span class="token class-name">ServiceBusBodyReq</span> txBody<span class="token punctuation">;</span> <span class="token annotation punctuation">@JacksonXmlProperty</span><span class="token punctuation">(</span>localName <span class="token operator">=</span> <span class="token string">"TX_EMB"</span><span class="token punctuation">)</span> <span class="token keyword">private</span> <span class="token class-name">String</span> txEmb<span class="token punctuation">;</span> <span class="token annotation punctuation">@JacksonXmlProperty</span><span class="token punctuation">(</span>localName <span class="token operator">=</span> <span class="token string">"ENTITY"</span><span class="token punctuation">)</span> <span class="token keyword">private</span> <span class="token class-name">ObjectNode</span> entity<span class="token punctuation">;</span> <span class="token keyword">private</span> <span class="token class-name">T</span> msgObject<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token comment">/*转换方法*/</span><span class="token keyword">private</span> <span class="token class-name">Req</span> <span class="token function">convert</span><span class="token punctuation">(</span><span class="token class-name">ObjectNode</span> entityStr<span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">ClassNotFoundException</span> <span class="token punctuation">{</span> <span class="token class-name">Type</span><span class="token punctuation">[</span><span class="token punctuation">]</span> actualTypeArguments <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token class-name">ParameterizedTypeImpl</span><span class="token punctuation">)</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">getClass</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getGenericSuperclass</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getActualTypeArguments</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>actualTypeArguments<span class="token punctuation">.</span>length <span class="token operator">!=</span> <span class="token number">2</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">ServiceException</span><span class="token punctuation">(</span><span class="token string">"对象获取异常"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token class-name">Object</span> o <span class="token operator">=</span> xmlMapper<span class="token punctuation">.</span><span class="token function">convertValue</span><span class="token punctuation">(</span>entityStr<span class="token punctuation">,</span> <span class="token class-name">Class</span><span class="token punctuation">.</span><span class="token function">forName</span><span class="token punctuation">(</span>actualTypeArguments<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">getTypeName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token punctuation">(</span><span class="token class-name">Req</span><span class="token punctuation">)</span> o<span class="token punctuation">;</span> <span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h1 id="问题阶段二"><a href="#问题阶段二" class="headerlink" title="问题阶段二"></a>问题阶段二</h1><p>以上处理反序列化成对象,但有另一个问题,companys只获取到一个第二个节点,也就是NAME-2的值,NAME-1的值没有获取到<br><img src="https://github.com/EverSpring/picbed/blob/main/jackson-databaind-2.png" alt="在这里插入图片描述"></p><h1 id="问题阶段三"><a href="#问题阶段三" class="headerlink" title="问题阶段三"></a>问题阶段三</h1><p>修改XmlDemoReqDto的定义,代码修改后如下:</p><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token annotation punctuation">@Data</span><span class="token annotation punctuation">@Builder</span><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">XmlDemoReqDto</span> <span class="token punctuation">{</span> <span class="token annotation punctuation">@JacksonXmlProperty</span><span class="token punctuation">(</span>localName <span class="token operator">=</span> <span class="token string">"USER_NAME"</span><span class="token punctuation">)</span> <span class="token keyword">private</span> <span class="token class-name">String</span> <span class="token class-name">UserName</span><span class="token punctuation">;</span> <span class="token comment">// 此处有变更</span> <span class="token annotation punctuation">@JacksonXmlProperty</span><span class="token punctuation">(</span>localName <span class="token operator">=</span> <span class="token string">"COMPANYS"</span><span class="token punctuation">)</span> <span class="token keyword">private</span> <span class="token class-name">Companys</span> companys<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token comment">// 新增一个Companys的对象,里面包含company list</span><span class="token annotation punctuation">@Data</span><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">Companys</span> <span class="token punctuation">{</span> <span class="token annotation punctuation">@JacksonXmlProperty</span><span class="token punctuation">(</span>localName <span class="token operator">=</span> <span class="token string">"COMPANY"</span><span class="token punctuation">)</span> <span class="token keyword">private</span> <span class="token class-name">List</span><span class="token generics"><span class="token punctuation"><</span><span class="token class-name">Company</span><span class="token punctuation">></span></span> companies<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token annotation punctuation">@Data</span><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">Company</span> <span class="token punctuation">{</span> <span class="token annotation punctuation">@JacksonXmlProperty</span><span class="token punctuation">(</span>localName <span class="token operator">=</span> <span class="token string">"COMPANYNAME"</span><span class="token punctuation">)</span> <span class="token keyword">private</span> <span class="token class-name">String</span> companyName<span class="token punctuation">;</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>按照上面的处理方式,可以正常解析出两个company了<br><img src="https://img-blog.csdnimg.cn/67e7906d1aa54e569c23e34d54b7c4bd.png" alt="在这里插入图片描述"></p><h1 id="问题阶段四"><a href="#问题阶段四" class="headerlink" title="问题阶段四"></a>问题阶段四</h1><p>以上方法在传入的XML中company如果是两个节点,那是正常的,但如果只有一个节点,也就是下面那种,就会出现解析失败的情况,出现异常“java.lang.IllegalArgumentException: Cannot deserialize value of type java.util.ArrayList<Company> from Object value (token JsonToken.START_OBJECT)”。因为jackson处理时把companys解析成了一个普通对象,而非list。解决方法:在Companys对象中添加@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)。代码见下面</p><pre class="line-numbers language-xml" data-language="xml"><code class="language-xml"><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>TX</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>TX_HEADER</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>SYS_HDR_LEN</span><span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>SYS_PKG_VRSN</span><span class="token punctuation">></span></span>01<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>SYS_PKG_VRSN</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>TX_HEADER</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>TX_EMB</span><span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>ENTITY</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>USER_NAME</span><span class="token punctuation">></span></span>xcc<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>USER_NAME</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>COMPANYS</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>COMPANY</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>COMPANYNAME</span><span class="token punctuation">></span></span>NAME-1<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>COMPANYNAME</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>COMPANY</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>COMPANYS</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>ENTITY</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>TX</span><span class="token punctuation">></span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token annotation punctuation">@Data</span><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">Companys</span> <span class="token punctuation">{</span> <span class="token annotation punctuation">@JacksonXmlProperty</span><span class="token punctuation">(</span>localName <span class="token operator">=</span> <span class="token string">"COMPANY"</span><span class="token punctuation">)</span> <span class="token annotation punctuation">@JsonFormat</span><span class="token punctuation">(</span><span class="token keyword">with</span> <span class="token operator">=</span> <span class="token class-name">JsonFormat<span class="token punctuation">.</span>Feature</span><span class="token punctuation">.</span>ACCEPT_SINGLE_VALUE_AS_ARRAY<span class="token punctuation">)</span> <span class="token keyword">private</span> <span class="token class-name">List</span><span class="token generics"><span class="token punctuation"><</span><span class="token class-name">Company</span><span class="token punctuation">></span></span> companies<span class="token punctuation">;</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>处理以上四个阶段问题,消耗了我整整一天的时间,希望能给遇到相同问题的朋友一些解决思路。再次感谢ChatGPT在处理问题中给的一些思路,太有用了。<br><strong>勉励:未来被人工智能淘汰的不是工程师,而是不会运用人工智能的工程师</strong></p><h1 id="参考链接"><a href="#参考链接" class="headerlink" title="参考链接"></a>参考链接</h1><p><a href="https://github.com/FasterXML/jackson-databind/issues/2733">https://github.com/FasterXML/jackson-databind/issues/2733</a><br><a href="https://github.com/FasterXML/jackson-databind/issues/2732">https://github.com/FasterXML/jackson-databind/issues/2732</a><br><a href="https://github.com/FasterXML/jackson-dataformat-xml/issues/339">https://github.com/FasterXML/jackson-dataformat-xml/issues/339</a></p><br/><p>👽个人博客:<a href="https://everspring.github.io/">https://everspring.github.io/</a><br>👽公众号:爱历史的IT男</p>]]></content>
<categories>
<category> JAVA </category>
</categories>
<tags>
<tag> Java </tag>
<tag> jackson </tag>
</tags>
</entry>
<entry>
<title>Arthas查看SpringBoot配置及ognl ClassNotFoundException处理</title>
<link href="/2022/03/27/arthas-cha-kan-springboot-pei-zhi-ji-ognl-classnotfoundexception-chu-li/"/>
<url>/2022/03/27/arthas-cha-kan-springboot-pei-zhi-ji-ognl-classnotfoundexception-chu-li/</url>
<content type="html"><![CDATA[<p>能讲到这篇文章的同学已经知道Arthas是什么了,这里就不多余赘述,本文介绍一下通过Arthas查看SpringBoot工程的配置及曾遇到过的问题。<br>本文相关知识:<code>sc</code>,<code>ognl</code>,<code>spring配置保存的地方</code></p><blockquote><p>注意:ognl是3.5.0以后出现的</p></blockquote><ol><li>arthas有可以查看JVM环境变量的<code>sysenv</code>,也有可以查看和修改JVM的系统属性的<code>sysprop</code>,但SpringBoot配置文件的内容不是在环境变量和系统属性中的,而是在<code>ConfigurableApplicationContext</code>的<code>environment</code>。<code>ConfigurableApplicationContext</code>继承自<code>ApplicationContext</code>,在我们的工程中经常要用到ApplicationContext,可以从ApplicationContext入手拿到environment。</li><li>通过ognl表达式获取,ognl在java中运用广泛,比如Spring Cache的注解、Spring @Value注解都有用到。假如工程下有一个com.xxx.spring.util.SpringUtils(见文末)可以获取到ApplicationContext,想要获取到application.yml中在server.port的值,可以采用如下方法<pre class="line-numbers language-none"><code class="language-none">ognl '#context=@com.xxx.util.SpringUtils@applicationContext,#context.getEnvironment().getProperty("server.port")'<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><blockquote><p>#context –代表的变量<br>@com.xxx.util.SpringUtils –指定的类<br>@applicationContext –类的属性<br>#context.getEnvironment().getProperty(“server.port”) –通过context获取到environment属性,然后再通过environment获取到property的值</p></blockquote></li><li>有些情况下通过ognl获取applicationContext的时候会出现<code>ClassNotFoundException</code>,详情如下:<blockquote><p>Failed to execute ognl, exception message: ognl.OgnlException: Could not get static field applicationContext from class com.xxx.util.SpringUtils [java.lang.ClassNotFoundException: Unable to resolve class: com.xxx.util.SpringUtils], please check $HOME/logs/arthas/arthas.log for more details.</p></blockquote></li></ol><p>出现此类问题是由于classloader不是默认加载器导致,见官网issue:<a href="https://github.com/alibaba/arthas/issues/71">https://github.com/alibaba/arthas/issues/71</a><br><strong>解决方法:</strong> </p><ul><li>1.通过sc -d 查询出当前类的classloader<pre class="line-numbers language-none"><code class="language-none">sc -d com.xxx.util.SpringUtils<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><img src="https://raw.githubusercontent.com/EverSpring/picbed/main/202205082343338.png" alt="图1" style="zoom: 50%;" /></li></ul><p>获取到classLoaderHash值</p><ul><li>2.使用指定的classloader。ognl -c classloader的hash值<pre class="line-numbers language-none"><code class="language-none">ognl '#context=@com.jinju.juke.common.utils.spring.SpringUtils@applicationContext,#context.getEnvironment().getProperty("dev.name")' -c 20ad941<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre></li></ul><hr><p>SpringUtils的代码</p><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token annotation punctuation">@Component</span><span class="token keyword">public</span> <span class="token keyword">final</span> <span class="token keyword">class</span> <span class="token class-name">SpringUtils</span> <span class="token keyword">implements</span> <span class="token class-name">BeanFactoryPostProcessor</span><span class="token punctuation">,</span> <span class="token class-name">ApplicationContextAware</span><span class="token punctuation">{</span> <span class="token comment">/** Spring应用上下文环境 */</span> <span class="token keyword">private</span> <span class="token keyword">static</span> <span class="token class-name">ConfigurableListableBeanFactory</span> beanFactory<span class="token punctuation">;</span> <span class="token keyword">private</span> <span class="token keyword">static</span> <span class="token class-name">ApplicationContext</span> applicationContext<span class="token punctuation">;</span> <span class="token annotation punctuation">@Override</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">postProcessBeanFactory</span><span class="token punctuation">(</span><span class="token class-name">ConfigurableListableBeanFactory</span> beanFactory<span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">BeansException</span> <span class="token punctuation">{</span> <span class="token class-name">SpringUtils</span><span class="token punctuation">.</span>beanFactory <span class="token operator">=</span> beanFactory<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token annotation punctuation">@Override</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setApplicationContext</span><span class="token punctuation">(</span><span class="token class-name">ApplicationContext</span> applicationContext<span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">BeansException</span> <span class="token punctuation">{</span> <span class="token class-name">SpringUtils</span><span class="token punctuation">.</span>applicationContext <span class="token operator">=</span> applicationContext<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * 获取对象 * * @param name * @return Object 一个以所给名字注册的bean的实例 * @throws org.springframework.beans.BeansException * */</span> <span class="token annotation punctuation">@SuppressWarnings</span><span class="token punctuation">(</span><span class="token string">"unchecked"</span><span class="token punctuation">)</span> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token generics"><span class="token punctuation"><</span><span class="token class-name">T</span><span class="token punctuation">></span></span> <span class="token class-name">T</span> <span class="token function">getBean</span><span class="token punctuation">(</span><span class="token class-name">String</span> name<span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">BeansException</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span><span class="token class-name">T</span><span class="token punctuation">)</span> beanFactory<span class="token punctuation">.</span><span class="token function">getBean</span><span class="token punctuation">(</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>]]></content>
<categories>
<category> JAVA </category>
</categories>
<tags>
<tag> Arthas </tag>
<tag> Java </tag>
</tags>
</entry>
<entry>
<title>MySQL字符串相加引发的血案</title>
<link href="/2022/02/16/mysql-zi-fu-chuan-xiang-jia-yin-fa-de-xie-an/"/>
<url>/2022/02/16/mysql-zi-fu-chuan-xiang-jia-yin-fa-de-xie-an/</url>
<content type="html"><![CDATA[<p>晚上接到同事电话,说有几十张表的数据全被删除了,当时懵逼了。<br>先说背景:环境是MySQL 5.7.16,数据是在运维过程中运行的DELETE语句导致。选择其中一条为例</p><pre class="line-numbers language-SQL" data-language="SQL"><code class="language-SQL">delete from fcexam where bussno in ('GBD000000016323'+'GBD000000016325')<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>fcexam的bussno结构为varchar,本意是删除GBD000000016323、GBD000000016325这两条数据,但把,写成了+。delete from改成select查询一次,发现数据全被查出来了,所以delete的所有数据。<br><strong>原因分析</strong><br>这跟MySQL中字符串加减乘除、字符串与0/1比较有关。</p><h4 id="1-字符串加减乘除"><a href="#1-字符串加减乘除" class="headerlink" title="1. 字符串加减乘除"></a>1. 字符串加减乘除</h4><blockquote><p>在mysql当中,字符串类型间进行加减乘除运算的时候,会<code>截取字符串以数字开头的那一部分数字进行运算</code>,如果字符串前面没有数字,那么就只能截取的数值为0,那么进行加减的时候结果都是0,进行乘除的时候结果都是NULL<br>感谢链接作者:不姓马的小马哥<br>文章地址:<a href="https://www.jianshu.com/p/2ab2c0dc3cb5">https://www.jianshu.com/p/2ab2c0dc3cb5</a></p></blockquote><pre class="line-numbers language-none"><code class="language-none">select ('GBD000000016323'+'GBD000000016325'); --结果为0select ('GBD000000016323'/'GBD000000016325'); --结果为nullselect ('GBD000000016323'*'GBD000000016325'); --结果为0select ('1GBD000000016323'+'GBD000000016325'); --结果为1select ('1GBD000000016323'+'2GBD000000016325'); --结果为3select ('1GBD000000016323'/'GBD000000016325'); --结果为null<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h4 id="2-字符串与0、1比较"><a href="#2-字符串与0、1比较" class="headerlink" title="2. 字符串与0、1比较"></a>2. 字符串与0、1比较</h4><p>MySQL boolean类型0代表false,1代表true。字符串开头没有数字时与0、1比较,如果是和0比较,得到的结果是1也就是true,和其他数字比较结果是0也就是false</p><pre class="line-numbers language-none"><code class="language-none">select 'GBD000000016323'=0; --结果为1select '1GBD000000016323'=1; --结果为1<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre><p>所以在我们跑的脚本里面,因为bussno都是’GBD’开头,转换出来就是where 0 = 0,where条件结果为true就把所以数据都查询出来了。</p><pre class="line-numbers language-none"><code class="language-none">select * from fcexam where bussno in ('GBD000000016323'+'GBD000000016325'); --等于是select * from fcexam where 0 in (0);<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>假如bussno有3条数据,’GBD000000016323’,’GBD000000016325’,’2GBD000000016325’,用上面的SQL只能查出前面2条,最后一条因为是2开头所以查询不出来</p><h4 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h4><pre class="line-numbers language-SQL" data-language="SQL"><code class="language-SQL">delete from fcexam where bussno in ('GBD000000016323'+'GBD000000016325')<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>这条SQL相当于就是</p><pre class="line-numbers language-none"><code class="language-none">delete from fcexam where 0 in (0)<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>参考资料:</p><ol><li><a href="https://www.jianshu.com/p/2ab2c0dc3cb5">https://www.jianshu.com/p/2ab2c0dc3cb5</a></li><li><a href="https://stackoverflow.com/questions/22080382/mysql-why-comparing-a-string-to-0-gives-true">https://stackoverflow.com/questions/22080382/mysql-why-comparing-a-string-to-0-gives-true</a></li></ol>]]></content>
<categories>
<category> 数据库 </category>
</categories>
<tags>
<tag> MySQL </tag>
</tags>
</entry>
<entry>
<title>了解开源协议</title>
<link href="/2022/02/12/kai-yuan-xie-yi/"/>
<url>/2022/02/12/kai-yuan-xie-yi/</url>
<content type="html"><![CDATA[<p>最近关于开源代码的新闻层出不穷,比如fake.js作者删除了所有代码引起的争论战火。而牵引开源代码的线–开源协议也被大家重视起来,之前国内开发人员对开源协议不太重视,随便找了几个周边的同行,对各种开源协议都分不清楚。网上了解了一翻,做个总结</p><p>感谢以下文章、视频作者提供资料,如有侵权请联系。</p><ol><li><a href="https://www.bilibili.com/video/BV1i3411b7xp?from=search&seid=7966784787421644790&spm_id_from=333.337.0.0">《最流行的开源协议什么,如何选择合适的开源协议?中国第一个违反GPL的案例,腾讯影音为什么会被ffmepg谴责——TechParty1204小沙龙第2个主题分享》</a></li><li><a href="https://www.runoob.com/w3cnote/open-source-license.html">《各种开源协议介绍》</a></li></ol><h3 id="一、-开源协议的六个特性"><a href="#一、-开源协议的六个特性" class="headerlink" title="一、 开源协议的六个特性"></a>一、 开源协议的六个特性</h3><p><img src="https://raw.githubusercontent.com/EverSpring/picbed/main/202205082344847.png" alt="image-20220213004304500"></p><h3 id="二、如何选择开源协议"><a href="#二、如何选择开源协议" class="headerlink" title="二、如何选择开源协议"></a>二、如何选择开源协议</h3><p><img src="https://raw.githubusercontent.com/EverSpring/picbed/main/202205082344287.png" alt="img"></p>]]></content>
<categories>
<category> 架构 </category>
</categories>
<tags>
<tag> 规范 </tag>
</tags>
</entry>
<entry>
<title>drools-7入门</title>
<link href="/2022/01/26/drools-7/"/>
<url>/2022/01/26/drools-7/</url>
<content type="html"><![CDATA[<p>这一部分学习的时候是看的黑马博学谷的学习视频。下面笔记也是随堂笔记。<br>笔者放在这里是为了方便观看,如有侵权,请联系删除。<br>注意:SpringBoot版本和Drools版本直接的兼容问题。<br>Maven仓库:</p><p>Drools:<a href="https://mvnrepository.com/artifact/org.kie/kie-spring">https://mvnrepository.com/artifact/org.kie/kie-spring</a> </p><p>SpringBoot: <a href="https://mvnrepository.com/artifact/org.springframework.boot/spring-boot">https://mvnrepository.com/artifact/org.springframework.boot/spring-boot</a></p><p>SpringBoot是2.0.x 对应的Drools用的7.6.x</p><p>SpringBoot 1.4.5 对应的Drools应该是7.0.x</p><h2 id="1-问题引出"><a href="#1-问题引出" class="headerlink" title="1. 问题引出"></a>1. 问题引出</h2><p>现有一个在线申请信用卡的业务场景,用户需要录入个人信息,如下图所示:</p><p><img src="/media/pictures/Drools.assets/image-20200114163727767.png" alt="image-20200114163727767"></p><p>通过上图可以看到,用户录入的个人信息包括姓名、性别、年龄、学历、电话、所在公司、职位、月收入、是否有房、是否有车、是否有信用卡等。录入完成后点击申请按钮提交即可。</p><p>用户提交申请后,需要在系统的服务端进行<strong>用户信息合法性检查</strong>(是否有资格申请信用卡),只有通过合法性检查的用户才可以成功申请到信用卡(注意:不同用户有可能申请到的信用卡额度不同)。</p><p>检查用户信息合法性的规则如下:</p><table><thead><tr><th align="left">规则编号</th><th align="left">名称</th><th align="left">描述</th></tr></thead><tbody><tr><td align="left">1</td><td align="left">检查学历与薪水1</td><td align="left">如果申请人既没房也没车,同时学历为大专以下,并且月薪少于5000,那么不通过</td></tr><tr><td align="left">2</td><td align="left">检查学历与薪水2</td><td align="left">如果申请人既没房也没车,同时学历为大专或本科,并且月薪少于3000,那么不通过</td></tr><tr><td align="left">3</td><td align="left">检查学历与薪水3</td><td align="left">如果申请人既没房也没车,同时学历为本科以上,并且月薪少于2000,同时之前没有信用卡的,那么不通过</td></tr><tr><td align="left">4</td><td align="left">检查申请人已有的信用卡数量</td><td align="left">如果申请人现有的信用卡数量大于10,那么不通过</td></tr></tbody></table><p>用户信息合法性检查通过后,还需要根据如下<strong>信用卡发放规则</strong>确定用户所办信用卡的额度:</p><table><thead><tr><th align="left">规则编号</th><th align="left">名称</th><th align="left">描述</th></tr></thead><tbody><tr><td align="left">1</td><td align="left">规则1</td><td align="left">如果申请人有房有车,或者月收入在20000以上,那么发放的信用卡额度为15000</td></tr><tr><td align="left">2</td><td align="left">规则2</td><td align="left">如果申请人没房没车,但月收入在10000~20000之间,那么发放的信用卡额度为6000</td></tr><tr><td align="left">3</td><td align="left">规则3</td><td align="left">如果申请人没房没车,月收入在10000以下,那么发放的信用卡额度为3000</td></tr><tr><td align="left">4</td><td align="left">规则4</td><td align="left">如果申请人有房没车或者没房但有车,月收入在10000以下,那么发放的信用卡额度为5000</td></tr><tr><td align="left">5</td><td align="left">规则5</td><td align="left">如果申请人有房没车或者是没房但有车,月收入在10000~20000之间,那么发放的信用卡额度为8000</td></tr></tbody></table><p>思考:如何实现上面的业务逻辑呢?</p><p>我们最容易想到的就是使用分支判断(if else)来实现,例如通过如下代码来检查用户信息合法性:</p><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token comment">//此处为伪代码</span><span class="token comment">//检查用户信息合法性,返回true表示检查通过,返回false表示检查不通过</span><span class="token keyword">public</span> <span class="token keyword">boolean</span> <span class="token function">checkUser</span><span class="token punctuation">(</span><span class="token class-name">User</span> user<span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token comment">//如果申请人既没房也没车,同时学历为大专以下,并且月薪少于5000,那么不通过</span> <span class="token keyword">if</span><span class="token punctuation">(</span>user<span class="token punctuation">.</span><span class="token function">getHouse</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token keyword">null</span> <span class="token operator">&&</span> user<span class="token punctuation">.</span><span class="token function">getcar</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token keyword">null</span> <span class="token operator">&&</span> user<span class="token punctuation">.</span><span class="token function">getEducation</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">equals</span><span class="token punctuation">(</span><span class="token string">"大专以下"</span><span class="token punctuation">)</span> <span class="token operator">&&</span> user<span class="token punctuation">.</span>getSalary <span class="token operator"><</span> <span class="token number">5000</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">//如果申请人既没房也没车,同时学历为大专或本科,并且月薪少于3000,那么不通过</span> <span class="token keyword">else</span> <span class="token keyword">if</span><span class="token punctuation">(</span>user<span class="token punctuation">.</span><span class="token function">getHouse</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token keyword">null</span> <span class="token operator">&&</span> user<span class="token punctuation">.</span><span class="token function">getcar</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token keyword">null</span> <span class="token operator">&&</span> user<span class="token punctuation">.</span><span class="token function">getEducation</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">equals</span><span class="token punctuation">(</span><span class="token string">"大专或本科"</span><span class="token punctuation">)</span> <span class="token operator">&&</span> user<span class="token punctuation">.</span>getSalary <span class="token operator"><</span> <span class="token number">3000</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">//如果申请人既没房也没车,同时学历为本科以上,并且月薪少于2000,同时之前没有信用卡的,那么不通过</span> <span class="token keyword">else</span> <span class="token keyword">if</span><span class="token punctuation">(</span>user<span class="token punctuation">.</span><span class="token function">getHouse</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token keyword">null</span> <span class="token operator">&&</span> user<span class="token punctuation">.</span><span class="token function">getcar</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token keyword">null</span> <span class="token operator">&&</span> user<span class="token punctuation">.</span><span class="token function">getEducation</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">equals</span><span class="token punctuation">(</span><span class="token string">"本科以上"</span><span class="token punctuation">)</span> <span class="token operator">&&</span> user<span class="token punctuation">.</span>getSalary <span class="token operator"><</span> <span class="token number">2000</span> <span class="token operator">&&</span> user<span class="token punctuation">.</span><span class="token function">getHasCreditCard</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">//如果申请人现有的信用卡数量大于10,那么不通过</span> <span class="token keyword">else</span> <span class="token keyword">if</span><span class="token punctuation">(</span>user<span class="token punctuation">.</span><span class="token function">getCreditCardCount</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">></span> <span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>如果用户信息合法性检查通过后,还需要通过如下代码确定用户所办信用卡的额度:</p><pre class="line-numbers language-none"><code class="language-none">//此处为伪代码//根据用户输入信息确定信用卡额度public Integer determineCreditCardLimit(User user){ //如果申请人有房有车,或者月收入在20000以上,那么发放的信用卡额度为15000 if((user.getHouse() != null && user.getcar() != null) || user.getSalary() > 20000){ return 15000; } //如果申请人没房没车,并且月收入在10000到20000之间,那么发放的信用卡额度为6000 else if(user.getHouse() == null && user.getcar() == null && user.getSalary() > 10000 && user.getSalary() < 20000){ return 6000; } //如果申请人没房没车,并且月收入在10000以下,那么发放的信用卡额度为3000 else if(user.getHouse() == null && user.getcar() == null && user.getSalary() < 10000){ return 3000; } //如果申请人有房没车或者没房但有车,并且月收入在10000以下,那么发放的信用卡额度为5000 else if((((user.getHouse() != null && user.getcar() == null) || (user.getHouse() == null && user.getcar() != null)) && user.getSalary() < 10000){ return 5000; } //如果申请人有房没车或者没房但有车,并且月收入在10000到20000之间,那么发放的信用卡额度为8000 else if((((user.getHouse() != null && user.getcar() == null) || (user.getHouse() == null && user.getcar() != null)) && (user.getSalary() > 10000 && user.getSalary() < 20000)){ return 8000; }}<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>通过上面的伪代码我们可以看到,我们的业务规则是通过Java代码的方式实现的。这种实现方式存在如下问题:</p><p>1、硬编码实现业务规则难以维护</p><p>2、硬编码实现业务规则难以应对变化</p><p>3、业务规则发生变化需要修改代码,重启服务后才能生效</p><p>那么面对上面的业务场景,还有什么好的实现方式吗?</p><p>答案是<strong>规则引擎</strong>。</p><h2 id="2-规则引擎概述"><a href="#2-规则引擎概述" class="headerlink" title="2. 规则引擎概述"></a>2. 规则引擎概述</h2><h3 id="2-1-什么是规则引擎"><a href="#2-1-什么是规则引擎" class="headerlink" title="2.1 什么是规则引擎"></a>2.1 什么是规则引擎</h3><p><strong>规则引擎</strong>,全称为<strong>业务规则管理系统</strong>,英文名为BRMS(即Business Rule Management System)。规则引擎的主要思想是将应用程序中的业务决策部分分离出来,并使用预定义的语义模块编写业务决策(业务规则),由用户或开发者在需要时进行配置、管理。</p><p>需要注意的是规则引擎并不是一个具体的技术框架,而是指的一类系统,即业务规则管理系统。目前市面上具体的规则引擎产品有:drools、VisualRules、iLog等。</p><p>规则引擎实现了将业务决策从应用程序代码中分离出来,接收数据输入,解释业务规则,并根据业务规则做出业务决策。规则引擎其实就是一个输入输出平台。</p><p>上面的申请信用卡业务场景使用规则引擎后效果如下:</p><p><img src="/media/pictures/Drools.assets/4.png" alt="4"></p><p>系统中引入规则引擎后,业务规则不再以程序代码的形式驻留在系统中,取而代之的是处理规则的规则引擎,业务规则存储在规则库中,完全独立于程序。业务人员可以像管理数据一样对业务规则进行管理,比如查询、添加、更新、统计、提交业务规则等。业务规则被加载到规则引擎中供应用系统调用。</p><h3 id="2-2-使用规则引擎的优势"><a href="#2-2-使用规则引擎的优势" class="headerlink" title="2.2 使用规则引擎的优势"></a>2.2 使用规则引擎的优势</h3><p>使用规则引擎的优势如下:</p><p>1、业务规则与系统代码分离,实现业务规则的集中管理</p><p>2、在不重启服务的情况下可随时对业务规则进行扩展和维护</p><p>3、可以动态修改业务规则,从而快速响应需求变更</p><p>4、规则引擎是相对独立的,只关心业务规则,使得业务分析人员也可以参与编辑、维护系统的业务规则</p><p>5、减少了硬编码业务规则的成本和风险</p><p>6、使用规则引擎提供的规则编辑工具,使复杂的业务规则实现变得的简单</p><h3 id="2-3-规则引擎应用场景"><a href="#2-3-规则引擎应用场景" class="headerlink" title="2.3 规则引擎应用场景"></a>2.3 规则引擎应用场景</h3><p>对于一些存在比较复杂的业务规则并且业务规则会频繁变动的系统比较适合使用规则引擎,如下:</p><p>1、风险控制系统—-风险贷款、风险评估</p><p>2、反欺诈项目—-银行贷款、征信验证</p><p>3、决策平台系统—-财务计算</p><p>4、促销平台系统—-满减、打折、加价购</p><h3 id="2-4-Drools介绍"><a href="#2-4-Drools介绍" class="headerlink" title="2.4 Drools介绍"></a>2.4 Drools介绍</h3><p>drools是一款由JBoss组织提供的基于Java语言开发的开源规则引擎,可以将复杂且多变的业务规则从硬编码中解放出来,以规则脚本的形式存放在文件或特定的存储介质中(例如存放在数据库中),使得业务规则的变更不需要修改项目代码、重启服务器就可以在线上环境立即生效。</p><p>drools官网地址:<a href="https://drools.org/">https://drools.org/</a></p><p>drools源码下载地址:<a href="https://github.com/kiegroup/drools">https://github.com/kiegroup/drools</a></p><p>在项目中使用drools时,即可以单独使用也可以整合spring使用。如果单独使用只需要导入如下maven坐标即可:</p><pre class="line-numbers language-xml" data-language="xml"><code class="language-xml"><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.drools<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>drools-compiler<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>7.6.0.Final<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>如果我们使用IDEA开发drools应用,IDEA中已经集成了drools插件。如果使用eclipse开发drools应用还需要单独安装drools插件。</p><p>drools API开发步骤如下:<img src="/media/pictures/Drools.assets/5.png" alt="5"></p><h2 id="3-Drools入门案例"><a href="#3-Drools入门案例" class="headerlink" title="3. Drools入门案例"></a>3. Drools入门案例</h2><p>本小节通过一个Drools入门案例来让大家初步了解Drools的使用方式、对Drools有一个整体概念。</p><h3 id="3-1-业务场景说明"><a href="#3-1-业务场景说明" class="headerlink" title="3.1 业务场景说明"></a>3.1 业务场景说明</h3><p>业务场景:消费者在图书商城购买图书,下单后需要在支付页面显示订单优惠后的价格。具体优惠规则如下:</p><table><thead><tr><th align="left">规则编号</th><th align="left">规则名称</th><th align="left">描述</th></tr></thead><tbody><tr><td align="left">1</td><td align="left">规则一</td><td align="left">所购图书总价在100元以下的没有优惠</td></tr><tr><td align="left">2</td><td align="left">规则二</td><td align="left">所购图书总价在100到200元的优惠20元</td></tr><tr><td align="left">3</td><td align="left">规则三</td><td align="left">所购图书总价在200到300元的优惠50元</td></tr><tr><td align="left">4</td><td align="left">规则四</td><td align="left">所购图书总价在300元以上的优惠100元</td></tr></tbody></table><p>现在需要根据上面的规则计算优惠后的价格。</p><h3 id="3-2-开发实现"><a href="#3-2-开发实现" class="headerlink" title="3.2 开发实现"></a>3.2 开发实现</h3><p>第一步:创建maven工程drools_quickstart并导入drools相关maven坐标</p><pre class="line-numbers language-xml" data-language="xml"><code class="language-xml"><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.drools<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>drools-compiler<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>7.10.0.Final<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>junit<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>junit<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>4.12<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>第二步:根据drools要求创建resources/META-INF/kmodule.xml配置文件</p><pre class="line-numbers language-xml" data-language="xml"><code class="language-xml"><span class="token prolog"><?xml version="1.0" encoding="UTF-8" ?></span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>kmodule</span> <span class="token attr-name">xmlns</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>http://www.drools.org/xsd/kmodule<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token comment"><!-- name:指定kbase的名称,可以任意,但是需要唯一 packages:指定规则文件的目录,需要根据实际情况填写,否则无法加载到规则文件 default:指定当前kbase是否为默认 --></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>kbase</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>myKbase1<span class="token punctuation">"</span></span> <span class="token attr-name">packages</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>rules<span class="token punctuation">"</span></span> <span class="token attr-name">default</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>true<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token comment"><!-- name:指定ksession名称,可以任意,但是需要唯一 default:指定当前session是否为默认 --></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>ksession</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>ksession-rule<span class="token punctuation">"</span></span> <span class="token attr-name">default</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>true<span class="token punctuation">"</span></span><span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>kbase</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>kmodule</span><span class="token punctuation">></span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>注意:上面配置文件的名称和位置都是固定写法,不能更改</p><p>第三步:创建实体类Order</p><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">package</span> <span class="token namespace">com<span class="token punctuation">.</span>itheima<span class="token punctuation">.</span>drools<span class="token punctuation">.</span>entity</span><span class="token punctuation">;</span><span class="token comment">/** * 订单 */</span><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">Order</span> <span class="token punctuation">{</span> <span class="token keyword">private</span> <span class="token class-name">Double</span> originalPrice<span class="token punctuation">;</span><span class="token comment">//订单原始价格,即优惠前价格</span> <span class="token keyword">private</span> <span class="token class-name">Double</span> realPrice<span class="token punctuation">;</span><span class="token comment">//订单真实价格,即优惠后价格</span> <span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token string">"Order{"</span> <span class="token operator">+</span> <span class="token string">"originalPrice="</span> <span class="token operator">+</span> originalPrice <span class="token operator">+</span> <span class="token string">", realPrice="</span> <span class="token operator">+</span> realPrice <span class="token operator">+</span> <span class="token char">'}'</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token class-name">Double</span> <span class="token function">getOriginalPrice</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> originalPrice<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setOriginalPrice</span><span class="token punctuation">(</span><span class="token class-name">Double</span> originalPrice<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>originalPrice <span class="token operator">=</span> originalPrice<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token class-name">Double</span> <span class="token function">getRealPrice</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> realPrice<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setRealPrice</span><span class="token punctuation">(</span><span class="token class-name">Double</span> realPrice<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>realPrice <span class="token operator">=</span> realPrice<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>第四步:创建规则文件resources/rules/bookDiscount.drl</p><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token comment">//图书优惠规则</span><span class="token keyword">package</span> <span class="token namespace">book<span class="token punctuation">.</span>discount</span><span class="token keyword">import</span> <span class="token namespace">com<span class="token punctuation">.</span>itheima<span class="token punctuation">.</span>drools<span class="token punctuation">.</span>entity<span class="token punctuation">.</span></span><span class="token class-name">Order</span><span class="token comment">//规则一:所购图书总价在100元以下的没有优惠</span>rule <span class="token string">"book_discount_1"</span> when $order<span class="token operator">:</span><span class="token class-name">Order</span><span class="token punctuation">(</span>originalPrice <span class="token operator"><</span> <span class="token number">100</span><span class="token punctuation">)</span> then $order<span class="token punctuation">.</span><span class="token function">setRealPrice</span><span class="token punctuation">(</span>$order<span class="token punctuation">.</span><span class="token function">getOriginalPrice</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"成功匹配到规则一:所购图书总价在100元以下的没有优惠"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>end<span class="token comment">//规则二:所购图书总价在100到200元的优惠20元</span>rule <span class="token string">"book_discount_2"</span> when $order<span class="token operator">:</span><span class="token class-name">Order</span><span class="token punctuation">(</span>originalPrice <span class="token operator"><</span> <span class="token number">200</span> <span class="token operator">&&</span> originalPrice <span class="token operator">>=</span> <span class="token number">100</span><span class="token punctuation">)</span> then $order<span class="token punctuation">.</span><span class="token function">setRealPrice</span><span class="token punctuation">(</span>$order<span class="token punctuation">.</span><span class="token function">getOriginalPrice</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">20</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"成功匹配到规则二:所购图书总价在100到200元的优惠20元"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>end<span class="token comment">//规则三:所购图书总价在200到300元的优惠50元</span>rule <span class="token string">"book_discount_3"</span> when $order<span class="token operator">:</span><span class="token class-name">Order</span><span class="token punctuation">(</span>originalPrice <span class="token operator"><=</span> <span class="token number">300</span> <span class="token operator">&&</span> originalPrice <span class="token operator">>=</span> <span class="token number">200</span><span class="token punctuation">)</span> then $order<span class="token punctuation">.</span><span class="token function">setRealPrice</span><span class="token punctuation">(</span>$order<span class="token punctuation">.</span><span class="token function">getOriginalPrice</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">50</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"成功匹配到规则三:所购图书总价在200到300元的优惠50元"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>end<span class="token comment">//规则四:所购图书总价在300元以上的优惠100元</span>rule <span class="token string">"book_discount_4"</span> when $order<span class="token operator">:</span><span class="token class-name">Order</span><span class="token punctuation">(</span>originalPrice <span class="token operator">>=</span> <span class="token number">300</span><span class="token punctuation">)</span> then $order<span class="token punctuation">.</span><span class="token function">setRealPrice</span><span class="token punctuation">(</span>$order<span class="token punctuation">.</span><span class="token function">getOriginalPrice</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"成功匹配到规则四:所购图书总价在300元以上的优惠100元"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>end<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>第五步:编写单元测试</p><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token annotation punctuation">@Test</span><span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">test1</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token class-name">KieServices</span> kieServices <span class="token operator">=</span> <span class="token class-name">KieServices<span class="token punctuation">.</span>Factory</span><span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">KieContainer</span> kieClasspathContainer <span class="token operator">=</span> kieServices<span class="token punctuation">.</span><span class="token function">getKieClasspathContainer</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//会话对象,用于和规则引擎交互</span> <span class="token class-name">KieSession</span> kieSession <span class="token operator">=</span> kieClasspathContainer<span class="token punctuation">.</span><span class="token function">newKieSession</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//构造订单对象,设置原始价格,由规则引擎根据优惠规则计算优惠后的价格</span> <span class="token class-name">Order</span> order <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Order</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> order<span class="token punctuation">.</span><span class="token function">setOriginalPrice</span><span class="token punctuation">(</span><span class="token number">210D</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//将数据提供给规则引擎,规则引擎会根据提供的数据进行规则匹配</span> kieSession<span class="token punctuation">.</span><span class="token function">insert</span><span class="token punctuation">(</span>order<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//激活规则引擎,如果规则匹配成功则执行规则</span> kieSession<span class="token punctuation">.</span><span class="token function">fireAllRules</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//关闭会话</span> kieSession<span class="token punctuation">.</span><span class="token function">dispose</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"优惠前原始价格:"</span> <span class="token operator">+</span> order<span class="token punctuation">.</span><span class="token function">getOriginalPrice</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token string">",优惠后价格:"</span> <span class="token operator">+</span> order<span class="token punctuation">.</span><span class="token function">getRealPrice</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>通过上面的入门案例我们可以发现,使用drools规则引擎主要工作就是编写规则文件,在规则文件中定义跟业务相关的业务规则,例如本案例定义的就是图书优惠规则。规则定义好后就需要调用drools提供的API将数据提供给规则引擎进行规则模式匹配,规则引擎会执行匹配成功的规则并将计算的结果返回给我们。</p><p>可能大家会有疑问,就是我们虽然没有在代码中编写规则的判断逻辑,但是我们还是在规则文件中编写了业务规则,这跟在代码中编写规则有什么本质的区别呢?</p><p>我们前面其实已经提到,使用规则引擎时业务规则可以做到动态管理。业务人员可以像管理数据一样对业务规则进行管理,比如查询、添加、更新、统计、提交业务规则等。这样就可以做到在不重启服务的情况下调整业务规则。</p><h3 id="3-3-小结"><a href="#3-3-小结" class="headerlink" title="3.3 小结"></a>3.3 小结</h3><h4 id="3-3-1-规则引擎构成"><a href="#3-3-1-规则引擎构成" class="headerlink" title="3.3.1 规则引擎构成"></a>3.3.1 规则引擎构成</h4><p>drools规则引擎由以下三部分构成:</p><ul><li>Working Memory(工作内存)</li><li>Rule Base(规则库)</li><li>Inference Engine(推理引擎)</li></ul><p>其中Inference Engine(推理引擎)又包括:</p><ul><li>Pattern Matcher(匹配器) 具体匹配哪一个规则,由这个完成</li><li>Agenda(议程)</li><li>Execution Engine(执行引擎)</li></ul><p>如下图所示:</p><p><img src="/media/pictures/Drools.assets/8.png" alt="8"></p><h4 id="3-3-2-相关概念说明"><a href="#3-3-2-相关概念说明" class="headerlink" title="3.3.2 相关概念说明"></a>3.3.2 相关概念说明</h4><p><strong>Working Memory</strong>:工作内存,drools规则引擎会从Working Memory中获取数据并和规则文件中定义的规则进行模式匹配,所以我们开发的应用程序只需要将我们的数据插入到Working Memory中即可,例如本案例中我们调用kieSession.insert(order)就是将order对象插入到了工作内存中。</p><p><strong>Fact</strong>:事实,是指在drools 规则应用当中,将一个<strong>普通的JavaBean插入到Working Memory后的对象</strong>就是Fact对象,例如本案例中的Order对象就属于Fact对象。Fact对象是我们的应用和规则引擎进行数据交互的桥梁或通道。</p><p><strong>Rule Base</strong>:规则库,我们在规则文件中定义的规则都会被加载到规则库中。</p><p><strong>Pattern Matcher</strong>:匹配器,将Rule Base中的所有规则与Working Memory中的Fact对象进行模式匹配,匹配成功的规则将被激活并放入Agenda中。</p><p><strong>Agenda</strong>:议程,用于存放通过匹配器进行模式匹配后被激活的规则。</p><p><strong>Execution Engine</strong>:执行引擎,执行Agenda中被激活的规则。</p><h4 id="3-3-3-规则引擎执行过程"><a href="#3-3-3-规则引擎执行过程" class="headerlink" title="3.3.3 规则引擎执行过程"></a>3.3.3 规则引擎执行过程</h4><p><img src="/media/pictures/Drools.assets/10.png" alt="10"></p><h4 id="3-3-4-KIE介绍"><a href="#3-3-4-KIE介绍" class="headerlink" title="3.3.4 KIE介绍"></a>3.3.4 KIE介绍</h4><p>我们在操作Drools时经常使用的API以及它们之间的关系如下图:</p><p><img src="/media/pictures/Drools.assets/9.png" alt="9"></p><p>通过上面的核心API可以发现,大部分类名都是以Kie开头。<strong>Kie全称为Knowledge Is Everything</strong>,即”知识就是一切”的缩写,是Jboss一系列项目的总称。如下图所示,Kie的主要模块有OptaPlanner、Drools、UberFire、jBPM。</p><p><img src="/media/pictures/Drools.assets/11.png" alt="11"></p><p>通过上图可以看到,Drools是整个KIE项目中的一个组件,Drools中还包括一个Drools-WB的模块,它是一个可视化的规则编辑器。</p><h2 id="4-Drools基础语法"><a href="#4-Drools基础语法" class="headerlink" title="4. Drools基础语法"></a>4. Drools基础语法</h2><h3 id="4-1-规则文件构成"><a href="#4-1-规则文件构成" class="headerlink" title="4.1 规则文件构成"></a>4.1 规则文件构成</h3><p>在使用Drools时非常重要的一个工作就是编写规则文件,通常规则文件的后缀为.drl。</p><p><strong>drl是Drools Rule Language的缩写</strong>。在规则文件中编写具体的规则内容。</p><p>一套完整的规则文件内容构成如下:</p><table><thead><tr><th align="left">关键字</th><th align="left">描述</th></tr></thead><tbody><tr><td align="left">package</td><td align="left">包名,只限于逻辑上的管理,同一个包名下的查询或者函数可以直接调用</td></tr><tr><td align="left">import</td><td align="left">用于导入类或者静态方法</td></tr><tr><td align="left">global</td><td align="left">全局变量</td></tr><tr><td align="left">function</td><td align="left">自定义函数</td></tr><tr><td align="left">query</td><td align="left">查询</td></tr><tr><td align="left">rule end</td><td align="left">规则体</td></tr></tbody></table><p>Drools支持的规则文件,除了drl形式,还有Excel文件类型的。</p><h3 id="4-2-规则体语法结构"><a href="#4-2-规则体语法结构" class="headerlink" title="4.2 规则体语法结构"></a>4.2 规则体语法结构</h3><p>规则体是规则文件内容中的重要组成部分,是进行业务规则判断、处理业务结果的部分。</p><p>规则体语法结构如下:</p><pre class="line-numbers language-java" data-language="java"><code class="language-java">rule <span class="token string">"ruleName"</span> attributes when LHS then RHSend<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p><strong>rule</strong>:关键字,表示规则开始,参数为规则的唯一名称。</p><p><strong>attributes</strong>:规则属性,是rule与when之间的参数,为可选项。</p><p><strong>when</strong>:关键字,后面跟规则的条件部分。</p><p><strong>LHS</strong>(Left Hand Side):是规则的条件部分的通用名称。它由零个或多个条件元素组成。<strong>如果LHS为空,则它将被视为始终为true的条件元素</strong>。 (左手边)</p><p><strong>then</strong>:关键字,后面跟规则的结果部分。</p><p><strong>RHS</strong>(Right Hand Side):是规则的后果或行动部分的通用名称。 (右手边)</p><p><strong>end</strong>:关键字,表示一个规则结束。</p><h3 id="4-3-注释"><a href="#4-3-注释" class="headerlink" title="4.3 注释"></a>4.3 注释</h3><p>在drl形式的规则文件中使用注释和Java类中使用注释一致,分为单行注释和多行注释。</p><p>单行注释用”//“进行标记,多行注释以”/<em>“开始,以”</em>/“结束。如下示例:</p><pre class="line-numbers language-drl" data-language="drl"><code class="language-drl">//规则rule1的注释,这是一个单行注释rule "rule1" when then System.out.println("rule1触发");end/*规则rule2的注释,这是一个多行注释*/rule "rule2" when then System.out.println("rule2触发");end<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h3 id="4-4-Pattern模式匹配"><a href="#4-4-Pattern模式匹配" class="headerlink" title="4.4 Pattern模式匹配"></a>4.4 Pattern模式匹配</h3><p>前面我们已经知道了Drools中的匹配器可以将Rule Base中的所有规则与Working Memory中的Fact对象进行模式匹配,那么我们就需要在规则体的LHS部分定义规则并进行模式匹配。LHS部分由一个或者多个条件组成,条件又称为pattern。</p><p><strong>pattern的语法结构为:绑定变量名:Object(Field约束)</strong></p><p>其中绑定变量名可以省略,通常绑定变量名的命名一般建议以$开始。如果定义了绑定变量名,就可以在规则体的RHS部分使用此绑定变量名来操作相应的Fact对象。Field约束部分是需要返回true或者false的0个或多个表达式。</p><p>例如我们的入门案例中:</p><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token comment">//规则二:所购图书总价在100到200元的优惠20元</span>rule <span class="token string">"book_discount_2"</span> when <span class="token comment">//Order为类型约束,originalPrice为属性约束</span> $order<span class="token operator">:</span><span class="token class-name">Order</span><span class="token punctuation">(</span>originalPrice <span class="token operator"><</span> <span class="token number">200</span> <span class="token operator">&&</span> originalPrice <span class="token operator">>=</span> <span class="token number">100</span><span class="token punctuation">)</span> then $order<span class="token punctuation">.</span><span class="token function">setRealPrice</span><span class="token punctuation">(</span>$order<span class="token punctuation">.</span><span class="token function">getOriginalPrice</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">20</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"成功匹配到规则二:所购图书总价在100到200元的优惠20元"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>end<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>通过上面的例子我们可以知道,匹配的条件为:</p><p>1、工作内存中必须存在Order这种类型的Fact对象—–类型约束</p><p>2、Fact对象的originalPrice属性值必须小于200——属性约束</p><p>3、Fact对象的originalPrice属性值必须大于等于100——属性约束</p><p>以上条件必须同时满足当前规则才有可能被激活。</p><p><strong>绑定变量既可以用在对象上,也可以用在对象的属性上</strong>。例如上面的例子可以改为:</p><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token comment">//规则二:所购图书总价在100到200元的优惠20元</span>rule <span class="token string">"book_discount_2"</span> when $order<span class="token operator">:</span><span class="token class-name">Order</span><span class="token punctuation">(</span>$op<span class="token operator">:</span>originalPrice <span class="token operator"><</span> <span class="token number">200</span> <span class="token operator">&&</span> originalPrice <span class="token operator">>=</span> <span class="token number">100</span><span class="token punctuation">)</span> then <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"$op="</span> <span class="token operator">+</span> $op<span class="token punctuation">)</span><span class="token punctuation">;</span> $order<span class="token punctuation">.</span><span class="token function">setRealPrice</span><span class="token punctuation">(</span>$order<span class="token punctuation">.</span><span class="token function">getOriginalPrice</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">20</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"成功匹配到规则二:所购图书总价在100到200元的优惠20元"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>end<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>LHS部分还可以定义多个pattern,多个pattern之间可以使用and或者or进行连接,也可以不写,默认连接为and。</p><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token comment">//规则二:所购图书总价在100到200元的优惠20元</span>rule <span class="token string">"book_discount_2"</span> when $order<span class="token operator">:</span><span class="token class-name">Order</span><span class="token punctuation">(</span>$op<span class="token operator">:</span>originalPrice <span class="token operator"><</span> <span class="token number">200</span> <span class="token operator">&&</span> originalPrice <span class="token operator">>=</span> <span class="token number">100</span><span class="token punctuation">)</span> and $customer<span class="token operator">:</span><span class="token class-name">Customer</span><span class="token punctuation">(</span>age <span class="token operator">></span> <span class="token number">20</span> <span class="token operator">&&</span> gender<span class="token operator">==</span><span class="token char">'male'</span><span class="token punctuation">)</span> then <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"$op="</span> <span class="token operator">+</span> $op<span class="token punctuation">)</span><span class="token punctuation">;</span> $order<span class="token punctuation">.</span><span class="token function">setRealPrice</span><span class="token punctuation">(</span>$order<span class="token punctuation">.</span><span class="token function">getOriginalPrice</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">20</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"成功匹配到规则二:所购图书总价在100到200元的优惠20元"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>end<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h3 id="4-5-比较操作符"><a href="#4-5-比较操作符" class="headerlink" title="4.5 比较操作符"></a>4.5 比较操作符</h3><p>Drools提供的比较操作符,如下表:</p><table><thead><tr><th align="left">符号</th><th align="left">说明</th></tr></thead><tbody><tr><td align="left">></td><td align="left">大于</td></tr><tr><td align="left"><</td><td align="left">小于</td></tr><tr><td align="left">>=</td><td align="left">大于等于</td></tr><tr><td align="left"><=</td><td align="left">小于等于</td></tr><tr><td align="left">==</td><td align="left">等于</td></tr><tr><td align="left">!=</td><td align="left">不等于</td></tr><tr><td align="left">contains</td><td align="left">检查一个Fact对象的某个属性值是否包含一个指定的对象值</td></tr><tr><td align="left">not contains</td><td align="left">检查一个Fact对象的某个属性值是否不包含一个指定的对象值</td></tr><tr><td align="left">memberOf</td><td align="left">判断一个Fact对象的某个属性是否在一个或多个集合中</td></tr><tr><td align="left">not memberOf</td><td align="left">判断一个Fact对象的某个属性是否不在一个或多个集合中</td></tr><tr><td align="left">matches</td><td align="left">判断一个Fact对象的属性是否与提供的标准的Java正则表达式进行匹配</td></tr><tr><td align="left">not matches</td><td align="left">判断一个Fact对象的属性是否不与提供的标准的Java正则表达式进行匹配</td></tr></tbody></table><p>前6个比较操作符和Java中的完全相同,下面我们重点学习后6个比较操作符。</p><h4 id="4-5-1-语法"><a href="#4-5-1-语法" class="headerlink" title="4.5.1 语法"></a>4.5.1 语法</h4><ul><li><p><strong>contains | not contains语法结构</strong></p><p>Object(Field[Collection/Array] contains value)</p><p>Object(Field[Collection/Array] not contains value)</p></li><li><p><strong>memberOf | not memberOf语法结构</strong></p><p>Object(field memberOf value[Collection/Array])</p><p>Object(field not memberOf value[Collection/Array])</p></li><li><p><strong>matches | not matches语法结构</strong></p><p>Object(field matches “正则表达式”)</p><p>Object(field not matches “正则表达式”)</p></li></ul><p>contain是前面包含后面,memberOf是后面包含前面。</p><h4 id="4-5-2-操作步骤"><a href="#4-5-2-操作步骤" class="headerlink" title="4.5.2 操作步骤"></a>4.5.2 操作步骤</h4><p>第一步:创建实体类,用于测试比较操作符</p><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">package</span> <span class="token namespace">com<span class="token punctuation">.</span>itheima<span class="token punctuation">.</span>drools<span class="token punctuation">.</span>entity</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">java<span class="token punctuation">.</span>util<span class="token punctuation">.</span></span><span class="token class-name">List</span><span class="token punctuation">;</span><span class="token comment">/** * 实体类 * 用于测试比较操作符 */</span><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">ComparisonOperatorEntity</span> <span class="token punctuation">{</span> <span class="token keyword">private</span> <span class="token class-name">String</span> names<span class="token punctuation">;</span> <span class="token keyword">private</span> <span class="token class-name">List</span><span class="token generics"><span class="token punctuation"><</span><span class="token class-name">String</span><span class="token punctuation">></span></span> list<span class="token punctuation">;</span> <span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">getNames</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> names<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setNames</span><span class="token punctuation">(</span><span class="token class-name">String</span> names<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>names <span class="token operator">=</span> names<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token class-name">List</span><span class="token generics"><span class="token punctuation"><</span><span class="token class-name">String</span><span class="token punctuation">></span></span> <span class="token function">getList</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> list<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setList</span><span class="token punctuation">(</span><span class="token class-name">List</span><span class="token generics"><span class="token punctuation"><</span><span class="token class-name">String</span><span class="token punctuation">></span></span> list<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>list <span class="token operator">=</span> list<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>第二步:在/resources/rules下创建规则文件comparisonOperator.drl</p><pre class="line-numbers language-drl" data-language="drl"><code class="language-drl">package comparisonOperatorimport com.itheima.drools.entity.ComparisonOperatorEntity/* 当前规则文件用于测试Drools提供的比较操作符*///测试比较操作符containsrule "rule_comparison_contains" when ComparisonOperatorEntity(names contains "张三") ComparisonOperatorEntity(list contains names) then System.out.println("规则rule_comparison_contains触发");end//测试比较操作符not containsrule "rule_comparison_notContains" when ComparisonOperatorEntity(names not contains "张三") ComparisonOperatorEntity(list not contains names) then System.out.println("规则rule_comparison_notContains触发");end//测试比较操作符memberOfrule "rule_comparison_memberOf" when ComparisonOperatorEntity(names memberOf list) then System.out.println("规则rule_comparison_memberOf触发");end//测试比较操作符not memberOfrule "rule_comparison_notMemberOf" when ComparisonOperatorEntity(names not memberOf list) then System.out.println("规则rule_comparison_notMemberOf触发");end//测试比较操作符matchesrule "rule_comparison_matches" when ComparisonOperatorEntity(names matches "张.*") then System.out.println("规则rule_comparison_matches触发");end//测试比较操作符not matchesrule "rule_comparison_notMatches" when ComparisonOperatorEntity(names not matches "张.*") then System.out.println("规则rule_comparison_notMatches触发");end<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>第三步:编写单元测试</p><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token comment">//测试比较操作符</span><span class="token annotation punctuation">@Test</span><span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">test3</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token class-name">KieServices</span> kieServices <span class="token operator">=</span> <span class="token class-name">KieServices<span class="token punctuation">.</span>Factory</span><span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">KieContainer</span> kieClasspathContainer <span class="token operator">=</span> kieServices<span class="token punctuation">.</span><span class="token function">getKieClasspathContainer</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">KieSession</span> kieSession <span class="token operator">=</span> kieClasspathContainer<span class="token punctuation">.</span><span class="token function">newKieSession</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">ComparisonOperatorEntity</span> comparisonOperatorEntity <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ComparisonOperatorEntity</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> comparisonOperatorEntity<span class="token punctuation">.</span><span class="token function">setNames</span><span class="token punctuation">(</span><span class="token string">"张三"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">List</span><span class="token generics"><span class="token punctuation"><</span><span class="token class-name">String</span><span class="token punctuation">></span></span> list <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ArrayList</span><span class="token generics"><span class="token punctuation"><</span><span class="token class-name">String</span><span class="token punctuation">></span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> list<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token string">"张三"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> list<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token string">"李四"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> comparisonOperatorEntity<span class="token punctuation">.</span><span class="token function">setList</span><span class="token punctuation">(</span>list<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//将数据提供给规则引擎,规则引擎会根据提供的数据进行规则匹配,如果规则匹配成功则执行规则</span> kieSession<span class="token punctuation">.</span><span class="token function">insert</span><span class="token punctuation">(</span>comparisonOperatorEntity<span class="token punctuation">)</span><span class="token punctuation">;</span> kieSession<span class="token punctuation">.</span><span class="token function">fireAllRules</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> kieSession<span class="token punctuation">.</span><span class="token function">dispose</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h3 id="4-6-执行指定规则"><a href="#4-6-执行指定规则" class="headerlink" title="4.6 执行指定规则"></a>4.6 执行指定规则</h3><p>通过前面的案例可以看到,我们在调用规则代码时,满足条件的规则都会被执行。那么如果我们只想执行其中的某个规则如何实现呢?</p><p>Drools给我们提供的方式是通过规则过滤器来实现执行指定规则。对于规则文件不用做任何修改,只需要修改Java代码即可,如下:</p><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token class-name">KieServices</span> kieServices <span class="token operator">=</span> <span class="token class-name">KieServices<span class="token punctuation">.</span>Factory</span><span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token class-name">KieContainer</span> kieClasspathContainer <span class="token operator">=</span> kieServices<span class="token punctuation">.</span><span class="token function">getKieClasspathContainer</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token class-name">KieSession</span> kieSession <span class="token operator">=</span> kieClasspathContainer<span class="token punctuation">.</span><span class="token function">newKieSession</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token class-name">ComparisonOperatorEntity</span> comparisonOperatorEntity <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ComparisonOperatorEntity</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>comparisonOperatorEntity<span class="token punctuation">.</span><span class="token function">setNames</span><span class="token punctuation">(</span><span class="token string">"张三"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token class-name">List</span><span class="token generics"><span class="token punctuation"><</span><span class="token class-name">String</span><span class="token punctuation">></span></span> list <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ArrayList</span><span class="token generics"><span class="token punctuation"><</span><span class="token class-name">String</span><span class="token punctuation">></span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>list<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token string">"张三"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>list<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token string">"李四"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>comparisonOperatorEntity<span class="token punctuation">.</span><span class="token function">setList</span><span class="token punctuation">(</span>list<span class="token punctuation">)</span><span class="token punctuation">;</span>kieSession<span class="token punctuation">.</span><span class="token function">insert</span><span class="token punctuation">(</span>comparisonOperatorEntity<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//通过规则过滤器实现只执行指定规则</span>kieSession<span class="token punctuation">.</span><span class="token function">fireAllRules</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">RuleNameEqualsAgendaFilter</span><span class="token punctuation">(</span><span class="token string">"rule_comparison_memberOf"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>kieSession<span class="token punctuation">.</span><span class="token function">dispose</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h3 id="4-7-关键字"><a href="#4-7-关键字" class="headerlink" title="4.7 关键字"></a>4.7 关键字</h3><p>Drools的关键字分为:硬关键字(Hard keywords)和软关键字(Soft keywords)。</p><p><strong>硬关键字是我们在规则文件中定义包名或者规则名时明确不能使用的,否则程序会报错</strong>。软关键字虽然可以使用,但是不建议使用。</p><p>硬关键字包括:true false null</p><p>软关键字包括:lock-on-active date-effective date-expires no-loop auto-focus activation-group agenda-group ruleflow-group entry-point duration package import dialect salience enabled attributes rule extend when then template query declare function global eval not in or and exists forall accumulate collect from action reverse result end over init</p><pre class="line-numbers language-java、、" data-language="java、、"><code class="language-java、、">比如:rule true //不可以rule "true" //可以<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre><h3 id="4-8-Drools内置方法"><a href="#4-8-Drools内置方法" class="headerlink" title="4.8 Drools内置方法"></a>4.8 Drools内置方法</h3><p>规则文件的<code>RHS</code>部分的主要作用是通过<strong>插入,删除或修改工作内存中的Fact数据</strong>,来达到控制规则引擎执行的目的。Drools提供了一些方法可以用来操作工作内存中的数据,<strong>操作完成后规则引擎会重新进行相关规则的匹配,</strong>原来没有匹配成功的规则在我们修改数据完成后有可能就会匹配成功了。</p><p>创建如下实体类:</p><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">package</span> <span class="token namespace">com<span class="token punctuation">.</span>itheima<span class="token punctuation">.</span>drools<span class="token punctuation">.</span>entity</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">java<span class="token punctuation">.</span>util<span class="token punctuation">.</span></span><span class="token class-name">List</span><span class="token punctuation">;</span><span class="token comment">/** * 学生 */</span><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">Student</span> <span class="token punctuation">{</span> <span class="token keyword">private</span> <span class="token keyword">int</span> id<span class="token punctuation">;</span> <span class="token keyword">private</span> <span class="token class-name">String</span> name<span class="token punctuation">;</span> <span class="token keyword">private</span> <span class="token keyword">int</span> age<span class="token punctuation">;</span> <span class="token keyword">public</span> <span class="token keyword">int</span> <span class="token function">getId</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> id<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setId</span><span class="token punctuation">(</span><span class="token keyword">int</span> id<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>id <span class="token operator">=</span> id<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> name<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setName</span><span class="token punctuation">(</span><span class="token class-name">String</span> name<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">int</span> <span class="token function">getAge</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> age<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setAge</span><span class="token punctuation">(</span><span class="token keyword">int</span> age<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>age <span class="token operator">=</span> age<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h4 id="4-8-1-update方法"><a href="#4-8-1-update方法" class="headerlink" title="4.8.1 update方法"></a>4.8.1 update方法</h4><p><strong>update方法的作用是更新工作内存中的数据,并让相关的规则重新匹配。</strong> (要避免死循环)</p><p>第一步:编写规则文件/resources/rules/student.drl,文件内容如</p><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">package</span> <span class="token namespace">student</span><span class="token keyword">import</span> <span class="token namespace">com<span class="token punctuation">.</span>itheima<span class="token punctuation">.</span>drools<span class="token punctuation">.</span>entity<span class="token punctuation">.</span></span><span class="token class-name">Student</span><span class="token comment">/* 当前规则文件用于测试Drools提供的内置方法*/</span>rule <span class="token string">"rule_student_age小于10岁"</span> when $s<span class="token operator">:</span><span class="token class-name">Student</span><span class="token punctuation">(</span>age <span class="token operator"><</span> <span class="token number">10</span><span class="token punctuation">)</span> then $s<span class="token punctuation">.</span><span class="token function">setAge</span><span class="token punctuation">(</span><span class="token number">15</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">update</span><span class="token punctuation">(</span>$s<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//更新数据,导致相关的规则会重新匹配</span> <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"规则rule_student_age小于10岁触发"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>endrule <span class="token string">"rule_student_age小于20岁同时大于10岁"</span> when $s<span class="token operator">:</span><span class="token class-name">Student</span><span class="token punctuation">(</span>age <span class="token operator"><</span> <span class="token number">20</span> <span class="token operator">&&</span> age <span class="token operator">></span> <span class="token number">10</span><span class="token punctuation">)</span> then $s<span class="token punctuation">.</span><span class="token function">setAge</span><span class="token punctuation">(</span><span class="token number">25</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">update</span><span class="token punctuation">(</span>$s<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//更新数据,导致相关的规则会重新匹配</span> <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"规则rule_student_age小于20岁同时大于10岁触发"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>endrule <span class="token string">"rule_student_age大于20岁"</span> when $s<span class="token operator">:</span><span class="token class-name">Student</span><span class="token punctuation">(</span>age <span class="token operator">></span> <span class="token number">20</span><span class="token punctuation">)</span> then <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"规则rule_student_age大于20岁触发"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>end<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>第二步:编写单元测试</p><pre class="line-numbers language-none"><code class="language-none">KieServices kieServices = KieServices.Factory.get();KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();KieSession kieSession = kieClasspathContainer.newKieSession();Student student = new Student();student.setAge(5);//将数据提供给规则引擎,规则引擎会根据提供的数据进行规则匹配,如果规则匹配成功则执行规则kieSession.insert(student);kieSession.fireAllRules();kieSession.dispose();<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>通过控制台的输出可以看到规则文件中定义的三个规则都触发了。</p><p>在更新数据时需要注意防止发生死循环。</p><h4 id="4-8-2-insert方法"><a href="#4-8-2-insert方法" class="headerlink" title="4.8.2 insert方法"></a>4.8.2 insert方法</h4><p>insert方法的作用是向工作内存中插入数据,并让相关的规则重新匹配。</p><p>第一步:修改student.drl文件内容如下</p><pre class="line-numbers language-none"><code class="language-none">package studentimport com.itheima.drools.entity.Student/* 当前规则文件用于测试Drools提供的内置方法*/rule "rule_insert_student_age等于10岁" when $s:Student(age == 10) then //新生成对象,相当于age是0 Student student = new Student(); student.setName("xcc"); insert(student);//插入数据,导致相关的规则会重新匹配 //直接用update会导致死循环,因为一直等于10// $s.setName("xcc");// update($s); System.out.println("规则rule_insert_student_age等于10岁触发");endrule "rule_insert_student_age小于10岁" when $s:Student(age>0 && age < 10) then $s.setAge(15); update($s); System.out.println("规则rule_insert_student_age小于10岁触发");endrule "rule_insert_student_age小于20岁同时大于10岁" when $s:Student(age < 20 && age > 10) then $s.setAge(25); update($s); System.out.println("规则rule_insert_student_age小于20岁同时大于10岁触发");endrule "rule_insert_student_age大于20岁" when $s:Student(age > 20) then System.out.println("规则rule_insert_student_age大于20岁触发");endrule "rule_insert_student_name添加名字" when $s:Student(name == "xcc") then System.out.println("添加了名字"+$s.getName());end<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>第二步:编写单元测试</p><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token class-name">KieServices</span> kieServices <span class="token operator">=</span> <span class="token class-name">KieServices<span class="token punctuation">.</span>Factory</span><span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token class-name">KieContainer</span> kieClasspathContainer <span class="token operator">=</span> kieServices<span class="token punctuation">.</span><span class="token function">getKieClasspathContainer</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token class-name">KieSession</span> kieSession <span class="token operator">=</span> kieClasspathContainer<span class="token punctuation">.</span><span class="token function">newKieSession</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token class-name">Student</span> student <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Student</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>student<span class="token punctuation">.</span><span class="token function">setAge</span><span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//将数据提供给规则引擎,规则引擎会根据提供的数据进行规则匹配,如果规则匹配成功则执行规则</span>kieSession<span class="token punctuation">.</span><span class="token function">insert</span><span class="token punctuation">(</span>student<span class="token punctuation">)</span><span class="token punctuation">;</span>kieSession<span class="token punctuation">.</span><span class="token function">fireAllRules</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>kieSession<span class="token punctuation">.</span><span class="token function">dispose</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>通过控制台输出可以发现,四个规则都触发了,这是因为首先进行规则匹配时只有第一个规则可以匹配成功,但是在第一个规则中向工作内存中插入了一个数据导致重新进行规则匹配,此时第二个规则可以匹配成功。在第二个规则中进行了数据修改导致第三个规则也可以匹配成功,以此类推最终四个规则都匹配成功并执行了。</p><h4 id="4-8-3-retract方法"><a href="#4-8-3-retract方法" class="headerlink" title="4.8.3 retract方法"></a>4.8.3 retract方法</h4><p><strong>retract方法的作用是删除工作内存中的数据,并让相关的规则重新匹配。</strong></p><p>第一步:修改student.drl文件内容如下</p><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">package</span> <span class="token namespace">student</span><span class="token keyword">import</span> <span class="token namespace">com<span class="token punctuation">.</span>itheima<span class="token punctuation">.</span>drools<span class="token punctuation">.</span>entity<span class="token punctuation">.</span></span><span class="token class-name">Student</span><span class="token comment">/* 当前规则文件用于测试Drools提供的内置方法*/</span>rule <span class="token string">"rule_student_age等于10岁时删除数据"</span> <span class="token comment">/* salience:设置当前规则的执行优先级,数值越大越优先执行,默认值为0. 因为当前规则的匹配条件和下面规则的匹配条件相同,为了保证先执行当前规则,需要设置优先级 */</span> salience <span class="token number">100</span> when $s<span class="token operator">:</span><span class="token class-name">Student</span><span class="token punctuation">(</span>age <span class="token operator">==</span> <span class="token number">10</span><span class="token punctuation">)</span> then <span class="token function">retract</span><span class="token punctuation">(</span>$s<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//retract方法的作用是删除工作内存中的数据,并让相关的规则重新匹配。</span> <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"规则rule_student_age等于10岁时删除数据触发"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>endrule <span class="token string">"rule_student_age等于10岁"</span> when $s<span class="token operator">:</span><span class="token class-name">Student</span><span class="token punctuation">(</span>age <span class="token operator">==</span> <span class="token number">10</span><span class="token punctuation">)</span> then <span class="token class-name">Student</span> student <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Student</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> student<span class="token punctuation">.</span><span class="token function">setAge</span><span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">insert</span><span class="token punctuation">(</span>student<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"规则rule_student_age等于10岁触发"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>endrule <span class="token string">"rule_student_age小于10岁"</span> when $s<span class="token operator">:</span><span class="token class-name">Student</span><span class="token punctuation">(</span>age <span class="token operator"><</span> <span class="token number">10</span><span class="token punctuation">)</span> then $s<span class="token punctuation">.</span><span class="token function">setAge</span><span class="token punctuation">(</span><span class="token number">15</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">update</span><span class="token punctuation">(</span>$s<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"规则rule_student_age小于10岁触发"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>endrule <span class="token string">"rule_student_age小于20岁同时大于10岁"</span> when $s<span class="token operator">:</span><span class="token class-name">Student</span><span class="token punctuation">(</span>age <span class="token operator"><</span> <span class="token number">20</span> <span class="token operator">&&</span> age <span class="token operator">></span> <span class="token number">10</span><span class="token punctuation">)</span> then $s<span class="token punctuation">.</span><span class="token function">setAge</span><span class="token punctuation">(</span><span class="token number">25</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">update</span><span class="token punctuation">(</span>$s<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"规则rule_student_age小于20岁同时大于10岁触发"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>endrule <span class="token string">"rule_student_age大于20岁"</span> when $s<span class="token operator">:</span><span class="token class-name">Student</span><span class="token punctuation">(</span>age <span class="token operator">></span> <span class="token number">20</span><span class="token punctuation">)</span> then <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"规则rule_student_age大于20岁触发"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>end<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>第二步:编写单元测试</p><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token class-name">KieServices</span> kieServices <span class="token operator">=</span> <span class="token class-name">KieServices<span class="token punctuation">.</span>Factory</span><span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token class-name">KieContainer</span> kieClasspathContainer <span class="token operator">=</span> kieServices<span class="token punctuation">.</span><span class="token function">getKieClasspathContainer</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token class-name">KieSession</span> kieSession <span class="token operator">=</span> kieClasspathContainer<span class="token punctuation">.</span><span class="token function">newKieSession</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token class-name">Student</span> student <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Student</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>student<span class="token punctuation">.</span><span class="token function">setAge</span><span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//将数据提供给规则引擎,规则引擎会根据提供的数据进行规则匹配,如果规则匹配成功则执行规则</span>kieSession<span class="token punctuation">.</span><span class="token function">insert</span><span class="token punctuation">(</span>student<span class="token punctuation">)</span><span class="token punctuation">;</span>kieSession<span class="token punctuation">.</span><span class="token function">fireAllRules</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>kieSession<span class="token punctuation">.</span><span class="token function">dispose</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>通过控制台输出可以发现,只有第一个规则触发了,因为在第一个规则中将工作内存中的数据删除了导致第二个规则并没有匹配成功。</p><h2 id="5-规则属性-attributes"><a href="#5-规则属性-attributes" class="headerlink" title="5. 规则属性 attributes"></a>5. 规则属性 attributes</h2><p>前面我们已经知道了规则体的构成如下:</p><pre class="line-numbers language-java" data-language="java"><code class="language-java">rule <span class="token string">"ruleName"</span> attributes when LHS then RHSend<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>本章节就是针对规则体的<strong>attributes</strong>属性部分进行讲解。Drools中提供的属性如下表(部分属性):</p><table><thead><tr><th align="left">属性名</th><th align="left">说明</th></tr></thead><tbody><tr><td align="left">salience</td><td align="left">指定规则执行优先级</td></tr><tr><td align="left">dialect</td><td align="left">指定规则使用的语言类型,取值为java和mvel</td></tr><tr><td align="left">enabled</td><td align="left">指定规则是否启用</td></tr><tr><td align="left">date-effective</td><td align="left">指定规则生效时间</td></tr><tr><td align="left">date-expires</td><td align="left">指定规则失效时间</td></tr><tr><td align="left">activation-group</td><td align="left">激活分组,具有相同分组名称的规则只能有一个规则触发</td></tr><tr><td align="left">agenda-group</td><td align="left">议程分组,只有获取焦点的组中的规则才有可能触发</td></tr><tr><td align="left">timer</td><td align="left">定时器,指定规则触发的时间</td></tr><tr><td align="left">auto-focus</td><td align="left">自动获取焦点,一般结合agenda-group一起使用</td></tr><tr><td align="left">no-loop</td><td align="left">防止死循环</td></tr></tbody></table><h3 id="5-1-enabled属性"><a href="#5-1-enabled属性" class="headerlink" title="5.1 enabled属性"></a>5.1 enabled属性</h3><p>enabled属性对应的取值为true和false,默认值为true。</p><p>用于指定当前规则是否启用,如果设置的值为false则当前规则无论是否匹配成功都不会触发</p><pre class="line-numbers language-java" data-language="java"><code class="language-java">rule <span class="token string">"rule_comparison_notMemberOf"</span> <span class="token comment">//指定当前规则不可用,当前规则无论是否匹配成功都不会执行</span> enabled <span class="token boolean">false</span> when <span class="token class-name">ComparisonOperatorEntity</span><span class="token punctuation">(</span>names not memberOf list<span class="token punctuation">)</span> then <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"规则rule_comparison_notMemberOf触发"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>end<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h3 id="5-2-dialect属性"><a href="#5-2-dialect属性" class="headerlink" title="5.2 dialect属性"></a>5.2 dialect属性</h3><p>dialect属性用于指定当前规则使用的语言类型,取值为java和mvel,默认值为java。</p><p>注:mvel是一种基于java语法的表达式语言。</p><p>mvel像正则表达式一样,有直接支持集合、数组和字符串匹配的操作符。</p><p>mvel还提供了用来配置和构造字符串的模板语言。</p><p>mvel表达式内容包括属性表达式,布尔表达式,方法调用,变量赋值,函数定义等。</p><h3 id="5-3-salience属性"><a href="#5-3-salience属性" class="headerlink" title="5.3 salience属性"></a>5.3 salience属性</h3><p>salience属性用于指定规则的执行优先级,<strong>取值类型为Integer</strong>。<strong>数值越大越优先执行</strong>。每个规则都有一个默认的执行顺序,如果不设置salience属性,规则体的执行顺序为由上到下。</p><p>可以通过创建规则文件salience.drl来测试salience属性,内容如下:</p><pre class="line-numbers language-none"><code class="language-none">package test.saliencerule "rule_1" when eval(true) then System.out.println("规则rule_1触发");end rule "rule_2" when eval(true) then System.out.println("规则rule_2触发");endrule "rule_3" when eval(true) then System.out.println("规则rule_3触发");end<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>通过控制台可以看到,由于以上三个规则没有设置salience属性,所以执行的顺序是按照规则文件中规则的顺序由上到下执行的。接下来我们修改一下文件内容:</p><pre class="line-numbers language-none"><code class="language-none">package testsaliencerule "rule_1" salience 9 when eval(true) then System.out.println("规则rule_1触发");endrule "rule_2" salience 10 when eval(true) then System.out.println("规则rule_2触发");endrule "rule_3" salience 8 when eval(true) then System.out.println("规则rule_3触发");end<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>通过控制台可以看到,规则文件执行的顺序是按照我们设置的salience值由大到小顺序执行的。</p><p>建议在编写规则时使用salience属性明确指定执行优先级。</p><h3 id="5-4-no-loop属性"><a href="#5-4-no-loop属性" class="headerlink" title="5.4 no-loop属性"></a>5.4 no-loop属性</h3><p>no-loop属性用于防止死循环,当规则通过update之类的函数修改了Fact对象时,可能使当前规则再次被激活从而导致死循环。取值类型为Boolean,默认值为false。测试步骤如下:</p><p>第一步:编写规则文件/resource/rules/noloop.drl</p><pre class="line-numbers language-none"><code class="language-none">package testnoloopimport com.itheima.drools.entity.Student/* 此规则文件用于测试no-loop属性*/rule "rule_noloop" when // no-loop true $student:Student(age == 25) then update($student);//注意此处执行update会导致当前规则重新被激活 System.out.println("规则rule_noloop触发");end<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>第二步:编写单元测试</p><pre class="line-numbers language-none"><code class="language-none">KieServices kieServices = KieServices.Factory.get();KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();KieSession kieSession = kieClasspathContainer.newKieSession();Student student = new Student();student.setAge(25);//将数据提供给规则引擎,规则引擎会根据提供的数据进行规则匹配,如果规则匹配成功则执行规则kieSession.insert(student);kieSession.fireAllRules();kieSession.dispose();<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>通过控制台可以看到,由于我们没有设置no-loop属性的值,所以发生了死循环。接下来设置no-loop的值为true再次测试则不会发生死循环。</p><h3 id="5-5-activation-group属性"><a href="#5-5-activation-group属性" class="headerlink" title="5.5 activation-group属性"></a>5.5 activation-group属性</h3><p>activation-group属性是指<strong>激活分组</strong>,取值为String类型。具有相同分组名称的规则<strong>只能有一个规则</strong>被触发。</p><p>第一步:编写规则文件/resources/rules/activationgroup.drl</p><pre class="line-numbers language-none"><code class="language-none">package testactivationgroup/* 此规则文件用于测试activation-group属性*/ rule "rule_activationgroup_1" activation-group "mygroup" when then System.out.println("规则rule_activationgroup_1触发");endrule "rule_activationgroup_2" activation-group "mygroup" when then System.out.println("规则rule_activationgroup_2触发");end<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>第二步:编写单元测试</p><pre class="line-numbers language-none"><code class="language-none">KieServices kieServices = KieServices.Factory.get();KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();KieSession kieSession = kieClasspathContainer.newKieSession();kieSession.fireAllRules();kieSession.dispose();<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>通过控制台可以发现,上面的两个规则因为属于同一个分组,所以只有一个触发了。同一个分组中的多个规则如果都能够匹配成功,具体哪一个最终能够被触发可以通过salience属性确定。</p><h3 id="5-6-agenda-group属性"><a href="#5-6-agenda-group属性" class="headerlink" title="5.6 agenda-group属性"></a>5.6 agenda-group属性</h3><p>agenda-group属性为<strong>议程分组</strong>,属于另一种可控的规则执行方式。用户可以通过设置agenda-group来控制规则的执行,<strong>只有获取焦点的组</strong>中的规则才会被触发。agenda-group有一个默认值MAIN,通过drools.getRule()打印可以看出来</p><p>第一步:创建规则文件/resources/rules/agendagroup.drl</p><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">package</span> <span class="token namespace">testagendagroup</span><span class="token comment">/* 此规则文件用于测试agenda-group属性*/</span>rule <span class="token string">"rule_agendagroup_1"</span> agenda<span class="token operator">-</span>group <span class="token string">"myagendagroup_1"</span> when then <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"规则rule_agendagroup_1触发"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>endrule <span class="token string">"rule_agendagroup_2"</span> agenda<span class="token operator">-</span>group <span class="token string">"myagendagroup_1"</span> when then <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"规则rule_agendagroup_2触发"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>end<span class="token comment">//========================================================</span>rule <span class="token string">"rule_agendagroup_3"</span> agenda<span class="token operator">-</span>group <span class="token string">"myagendagroup_2"</span> when then <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"规则rule_agendagroup_3触发"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>endrule <span class="token string">"rule_agendagroup_4"</span> agenda<span class="token operator">-</span>group <span class="token string">"myagendagroup_2"</span> when then <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"规则rule_agendagroup_4触发"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>end<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>第二步:编写单元测试</p><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token class-name">KieServices</span> kieServices <span class="token operator">=</span> <span class="token class-name">KieServices<span class="token punctuation">.</span>Factory</span><span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token class-name">KieContainer</span> kieClasspathContainer <span class="token operator">=</span> kieServices<span class="token punctuation">.</span><span class="token function">getKieClasspathContainer</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token class-name">KieSession</span> kieSession <span class="token operator">=</span> kieClasspathContainer<span class="token punctuation">.</span><span class="token function">newKieSession</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//设置焦点,对应agenda-group分组中的规则才可能被触发</span><span class="token comment">//注意:是只对有agenda-group属性的有效,如果没有agenda-group,规则匹配了的也会触发,比如没有LHS的</span>kieSession<span class="token punctuation">.</span><span class="token function">getAgenda</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getAgendaGroup</span><span class="token punctuation">(</span><span class="token string">"myagendagroup_1"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">setFocus</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>kieSession<span class="token punctuation">.</span><span class="token function">fireAllRules</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>kieSession<span class="token punctuation">.</span><span class="token function">dispose</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>通过控制台可以看到,只有获取焦点的分组中的规则才会触发。<strong>与activation-group不同的是,activation-group定义的分组中只能够有一个规则可以被触发,而agenda-group分组中的多个规则都可以被触发</strong>。</p><h3 id="5-7-auto-focus属性"><a href="#5-7-auto-focus属性" class="headerlink" title="5.7 auto-focus属性"></a>5.7 auto-focus属性</h3><p>auto-focus属性为<strong>自动获取焦点</strong>,取值类型为Boolean,默认值为false。一般结合agenda-group属性使用,当一个议程分组未获取焦点时,可以设置auto-focus属性来控制。</p><p>第一步:修改/resources/rules/agendagroup.drl文件内容如下</p><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">package</span> <span class="token namespace">testagendagroup</span>rule <span class="token string">"rule_agendagroup_1"</span> agenda<span class="token operator">-</span>group <span class="token string">"myagendagroup_1"</span> when then <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"规则rule_agendagroup_1触发"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>endrule <span class="token string">"rule_agendagroup_2"</span> agenda<span class="token operator">-</span>group <span class="token string">"myagendagroup_1"</span> when then <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"规则rule_agendagroup_2触发"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>end<span class="token comment">//========================================================</span>rule <span class="token string">"rule_agendagroup_3"</span> agenda<span class="token operator">-</span>group <span class="token string">"myagendagroup_2"</span> auto<span class="token operator">-</span>focus <span class="token boolean">true</span> <span class="token comment">//自动获取焦点</span> when then <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"规则rule_agendagroup_3触发"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>endrule <span class="token string">"rule_agendagroup_4"</span> agenda<span class="token operator">-</span>group <span class="token string">"myagendagroup_2"</span> auto<span class="token operator">-</span>focus <span class="token boolean">true</span> <span class="token comment">//自动获取焦点</span> when then <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"规则rule_agendagroup_4触发"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>end<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>第二步:编写单元测试</p><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token class-name">KieServices</span> kieServices <span class="token operator">=</span> <span class="token class-name">KieServices<span class="token punctuation">.</span>Factory</span><span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token class-name">KieContainer</span> kieClasspathContainer <span class="token operator">=</span> kieServices<span class="token punctuation">.</span><span class="token function">getKieClasspathContainer</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token class-name">KieSession</span> kieSession <span class="token operator">=</span> kieClasspathContainer<span class="token punctuation">.</span><span class="token function">newKieSession</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>kieSession<span class="token punctuation">.</span><span class="token function">fireAllRules</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>kieSession<span class="token punctuation">.</span><span class="token function">dispose</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>通过控制台可以看到,设置auto-focus属性为true的规则都触发了。</p><p>注意:同一个组,只要有个设置auto-focus true 其他的设置不设置都无所谓啦。都会起作用的。</p><h3 id="5-8-timer属性"><a href="#5-8-timer属性" class="headerlink" title="5.8 timer属性"></a>5.8 timer属性</h3><p>timer属性可以通过定时器的方式指定规则执行的时间,使用方式有两种:</p><p><strong>方式一</strong>:timer (int: <initial delay> <repeat interval>?)</p><p>此种方式遵循java.util.Timer对象的使用方式,第一个参数表示几秒后执行,第二个参数表示每隔几秒执行一次,第二个参数为可选。</p><p><strong>方式二</strong>:timer(cron: <cron expression>) </p><p>此种方式使用标准的unix cron表达式的使用方式来定义规则执行的时间。</p><p>第一步:创建规则文件/resources/rules/timer.drl</p><pre class="line-numbers language-none"><code class="language-none">package testtimerimport java.text.SimpleDateFormatimport java.util.Date/* 此规则文件用于测试timer属性*/rule "rule_timer_1" timer (5s 2s) //含义:5秒后触发,然后每隔2秒触发一次 when then System.out.println("规则rule_timer_1触发,触发时间为:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));endrule "rule_timer_2" timer (cron:0/1 * * * * ?) //含义:每隔1秒触发一次 when then System.out.println("规则rule_timer_2触发,触发时间为:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));end<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>第二步:编写单元测试</p><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token class-name">KieServices</span> kieServices <span class="token operator">=</span> <span class="token class-name">KieServices<span class="token punctuation">.</span>Factory</span><span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token class-name">KieContainer</span> kieClasspathContainer <span class="token operator">=</span> kieServices<span class="token punctuation">.</span><span class="token function">getKieClasspathContainer</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">final</span> <span class="token class-name">KieSession</span> kieSession <span class="token operator">=</span> kieClasspathContainer<span class="token punctuation">.</span><span class="token function">newKieSession</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">new</span> <span class="token class-name">Thread</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">Runnable</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">run</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">//启动规则引擎进行规则匹配,直到调用halt方法才结束规则引擎</span> kieSession<span class="token punctuation">.</span><span class="token function">fireUntilHalt</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">start</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token class-name">Thread</span><span class="token punctuation">.</span><span class="token function">sleep</span><span class="token punctuation">(</span><span class="token number">10000</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//结束规则引擎</span>kieSession<span class="token punctuation">.</span><span class="token function">halt</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>kieSession<span class="token punctuation">.</span><span class="token function">dispose</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>注意:单元测试的代码和以前的有所不同,因为我们规则文件中使用到了timer进行定时执行,需要程序能够持续一段时间才能够看到定时器触发的效果。</p><h3 id="5-9-date-effective属性"><a href="#5-9-date-effective属性" class="headerlink" title="5.9 date-effective属性"></a>5.9 date-effective属性</h3><p>date-effective属性<strong>用于指定规则的生效时间</strong>,即只有当前系统时间大于等于设置的时间或者日期规则才有可能触发。默认日期格式为:dd-MMM-yyyy。用户也可以自定义日期格式。</p><p>第一步:编写规则文件/resources/rules/dateeffective.drl</p><pre class="line-numbers language-none"><code class="language-none">package testdateeffective/* 此规则文件用于测试date-effective属性*/rule "rule_dateeffective_1" date-effective "2020-10-01 10:00" when then System.out.println("规则rule_dateeffective_1触发");end<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>第二步:编写单元测试</p><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token comment">//设置日期格式</span><span class="token class-name">System</span><span class="token punctuation">.</span><span class="token function">setProperty</span><span class="token punctuation">(</span><span class="token string">"drools.dateformat"</span><span class="token punctuation">,</span><span class="token string">"yyyy-MM-dd HH:mm"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token class-name">KieServices</span> kieServices <span class="token operator">=</span> <span class="token class-name">KieServices<span class="token punctuation">.</span>Factory</span><span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token class-name">KieContainer</span> kieClasspathContainer <span class="token operator">=</span> kieServices<span class="token punctuation">.</span><span class="token function">getKieClasspathContainer</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token class-name">KieSession</span> kieSession <span class="token operator">=</span> kieClasspathContainer<span class="token punctuation">.</span><span class="token function">newKieSession</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>kieSession<span class="token punctuation">.</span><span class="token function">fireAllRules</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>kieSession<span class="token punctuation">.</span><span class="token function">dispose</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>注意:上面的代码需要设置日期格式,否则我们在规则文件中写的日期格式和默认的日期格式不匹配程序会报错。</p><h3 id="5-10-date-expires属性"><a href="#5-10-date-expires属性" class="headerlink" title="5.10 date-expires属性"></a>5.10 date-expires属性</h3><p>date-expires属性用于指定规则的<strong>失效时间</strong>,即只有当前系统时间小于设置的时间或者日期规则才有可能触发。默认日期格式为:dd-MMM-yyyy。用户也可以自定义日期格式。<br><strong>注意:</strong>如果有一个drl文件中用了自定义的日期格式,一定要设置全局变量,否则会编译报错</p><p>第一步:编写规则文件/resource/rules/dateexpires.drl</p><pre class="line-numbers language-none"><code class="language-none">package testdateexpires/* 此规则文件用于测试date-expires属性*/rule "rule_dateexpires_1" date-expires "2019-10-01 10:00" when then System.out.println("规则rule_dateexpires_1触发");end<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>第二步:编写单元测试</p><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token comment">//设置日期格式</span><span class="token class-name">System</span><span class="token punctuation">.</span><span class="token function">setProperty</span><span class="token punctuation">(</span><span class="token string">"drools.dateformat"</span><span class="token punctuation">,</span><span class="token string">"yyyy-MM-dd HH:mm"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token class-name">KieServices</span> kieServices <span class="token operator">=</span> <span class="token class-name">KieServices<span class="token punctuation">.</span>Factory</span><span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token class-name">KieContainer</span> kieClasspathContainer <span class="token operator">=</span> kieServices<span class="token punctuation">.</span><span class="token function">getKieClasspathContainer</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token class-name">KieSession</span> kieSession <span class="token operator">=</span> kieClasspathContainer<span class="token punctuation">.</span><span class="token function">newKieSession</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>kieSession<span class="token punctuation">.</span><span class="token function">fireAllRules</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>kieSession<span class="token punctuation">.</span><span class="token function">dispose</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>注意:上面的代码需要设置日期格式,否则我们在规则文件中写的日期格式和默认的日期格式不匹配程序会报错。</p><h2 id="6-Drools高级语法"><a href="#6-Drools高级语法" class="headerlink" title="6. Drools高级语法"></a>6. Drools高级语法</h2><p>前面章节我们已经知道了一套完整的规则文件内容构成如下:</p><table><thead><tr><th align="left">关键字</th><th align="left">描述</th></tr></thead><tbody><tr><td align="left">package</td><td align="left">包名,只限于逻辑上的管理,同一个包名下的查询或者函数可以直接调用</td></tr><tr><td align="left">import</td><td align="left">用于导入类或者静态方法</td></tr><tr><td align="left">global</td><td align="left">全局变量</td></tr><tr><td align="left">function</td><td align="left">自定义函数</td></tr><tr><td align="left">query</td><td align="left">查询</td></tr><tr><td align="left">rule end</td><td align="left">规则体</td></tr></tbody></table><p>本章节我们就来学习其中的几个关键字。</p><h3 id="6-1-global全局变量"><a href="#6-1-global全局变量" class="headerlink" title="6.1 global全局变量"></a>6.1 global全局变量</h3><p>global关键字用于在规则文件中<strong>定义全局变量</strong>,它可以让应用程序的对象在规则文件中能够被访问。可以用来为规则文件提供数据或服务。</p><p>语法结构为:<strong>global 对象类型 对象名称</strong></p><p>在使用global定义的全局变量时有两点需要注意:</p><p>1、如果对象类型为<strong>包装类型</strong>时,在一个规则中改变了global的值,那么<strong>只针对当前规则有效</strong>,对其他规则中的global不会有影响。可以理解为它是当前规则代码中的global副本,规则内部修改不会影响全局的使用。</p><p>2、如果对象类型为<strong>集合类型或JavaBean</strong>时,在一个规则中改变了global的值,对java代码和所有规则都有效。</p><p>下面我们通过代码进行验证:</p><p>第一步:创建UserService类</p><pre class="line-numbers language-none"><code class="language-none">package com.itheima.drools.service;public class UserService { public void save(){ System.out.println("UserService.save()..."); }}<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>第二步:编写规则文件/resources/rules/global.drl</p><pre class="line-numbers language-none"><code class="language-none">package testglobal/* 此规则文件用于测试global全局变量*/global java.lang.Integer count //定义一个包装类型的全局变量global com.itheima.drools.service.UserService userService //定义一个JavaBean类型的全局变量global java.util.List gList //定义一个集合类型的全局变量rule "rule_global_1" when then count += 10; //全局变量计算,只对当前规则有效,其他规则不受影响 userService.save();//调用全局变量的方法 gList.add("itcast");//向集合类型的全局变量中添加元素,Java代码和所有规则都受影响 gList.add("itheima"); System.out.println("count=" + count); System.out.println("gList.size=" + gList.size());endrule "rule_global_2" when then userService.save(); System.out.println("count=" + count); System.out.println("gList.size=" + gList.size());end<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>第三步:编写单元测试</p><pre class="line-numbers language-none"><code class="language-none">KieServices kieServices = KieServices.Factory.get();KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();KieSession kieSession = kieClasspathContainer.newKieSession();//设置全局变量,名称和类型必须和规则文件中定义的全局变量名称对应kieSession.setGlobal("userService",new UserService());kieSession.setGlobal("count",5);List list = new ArrayList();//size为0kieSession.setGlobal("gList",list);kieSession.fireAllRules();kieSession.dispose();//因为在规则中为全局变量添加了两个元素,所以现在的size为2System.out.println(list.size());<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>注意:</p><p>后面的代码中定义了全局变量以后,前面的test(用的fireAllRules()没有传参)都需要加,不然会出错。</p><h3 id="6-2-query查询"><a href="#6-2-query查询" class="headerlink" title="6.2 query查询"></a>6.2 query查询</h3><p>query查询提供了一种<strong>查询working memory中符合约束条件的Fact对象</strong>的简单方法。它仅包含规则文件中的LHS部分,不用指定“when”和“then”部分并且以end结束。具体语法结构如下:</p><pre class="line-numbers language-none"><code class="language-none">query 查询的名称(可选参数) LHSend<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre><p>具体操作步骤:</p><p>第一步:编写规则文件/resources/rules/query.drl</p><pre class="line-numbers language-none"><code class="language-none">package testqueryimport com.itheima.drools.entity.Student/* 此规则文件用于测试query查询*///不带参数的查询//当前query用于查询Working Memory中age>10的Student对象query "query_1" $student:Student(age > 10)end//带有参数的查询//当前query用于查询Working Memory中age>10同时name需要和传递的参数name相同的Student对象query "query_2"(String sname) $student:Student(age > 20 && name == sname)end<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>第二步:编写单元测试</p><pre class="line-numbers language-none"><code class="language-none">KieServices kieServices = KieServices.Factory.get();KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();KieSession kieSession = kieClasspathContainer.newKieSession();Student student1 = new Student();student1.setName("张三");student1.setAge(12);Student student2 = new Student();student2.setName("李四");student2.setAge(8);Student student3 = new Student();student3.setName("王五");student3.setAge(22);//将对象插入Working Memory中kieSession.insert(student1);kieSession.insert(student2);kieSession.insert(student3);//调用规则文件中的查询QueryResults results1 = kieSession.getQueryResults("query_1");int size = results1.size();System.out.println("size=" + size);for (QueryResultsRow row : results1) { Student student = (Student) row.get("$student"); System.out.println(student);}//调用规则文件中的查询QueryResults results2 = kieSession.getQueryResults("query_2","王五");size = results2.size();System.out.println("size=" + size);for (QueryResultsRow row : results2) { Student student = (Student) row.get("$student"); System.out.println(student);}//kieSession.fireAllRules();kieSession.dispose();<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h3 id="6-3-function函数"><a href="#6-3-function函数" class="headerlink" title="6.3 function函数"></a>6.3 function函数</h3><p>function关键字用于在规则文件中定义函数,就相当于java类中的方法一样。可以在规则体中调用定义的函数。使用函数的好处是可以将业务逻辑集中放置在一个地方,根据需要可以对函数进行修改。</p><p>函数定义的语法结构如下:</p><pre class="line-numbers language-java" data-language="java"><code class="language-java">function 返回值类型 函数名<span class="token punctuation">(</span>可选参数<span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token comment">//逻辑代码</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre><p>具体操作步骤:</p><p>第一步:编写规则文件/resources/rules/function.drl</p><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">package</span> <span class="token namespace">testfunction</span><span class="token keyword">import</span> <span class="token namespace">com<span class="token punctuation">.</span>itheima<span class="token punctuation">.</span>drools<span class="token punctuation">.</span>entity<span class="token punctuation">.</span></span><span class="token class-name">Student</span><span class="token comment">/* 此规则文件用于测试function函数*/</span><span class="token comment">//定义一个函数</span>function <span class="token class-name">String</span> <span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token class-name">String</span> name<span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token string">"hello "</span> <span class="token operator">+</span> name<span class="token punctuation">;</span><span class="token punctuation">}</span>rule <span class="token string">"rule_function_1"</span> when $student<span class="token operator">:</span><span class="token class-name">Student</span><span class="token punctuation">(</span>name <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span> then <span class="token comment">//调用上面定义的函数</span> <span class="token class-name">String</span> ret <span class="token operator">=</span> <span class="token function">sayHello</span><span class="token punctuation">(</span>$student<span class="token punctuation">.</span><span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>ret<span class="token punctuation">)</span><span class="token punctuation">;</span>end<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>第二步:编写单元测试</p><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token class-name">KieServices</span> kieServices <span class="token operator">=</span> <span class="token class-name">KieServices<span class="token punctuation">.</span>Factory</span><span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token class-name">KieContainer</span> kieClasspathContainer <span class="token operator">=</span> kieServices<span class="token punctuation">.</span><span class="token function">getKieClasspathContainer</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token class-name">KieSession</span> kieSession <span class="token operator">=</span> kieClasspathContainer<span class="token punctuation">.</span><span class="token function">newKieSession</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token class-name">Student</span> student <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Student</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>student<span class="token punctuation">.</span><span class="token function">setName</span><span class="token punctuation">(</span><span class="token string">"小明"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>kieSession<span class="token punctuation">.</span><span class="token function">insert</span><span class="token punctuation">(</span>student<span class="token punctuation">)</span><span class="token punctuation">;</span>kieSession<span class="token punctuation">.</span><span class="token function">fireAllRules</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>kieSession<span class="token punctuation">.</span><span class="token function">dispose</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h3 id="6-4-LHS加强"><a href="#6-4-LHS加强" class="headerlink" title="6.4 LHS加强"></a>6.4 LHS加强</h3><p>前面我们已经知道了在规则体中的LHS部分是<strong>介于when和then之间的部分</strong>,主要用于模式匹配,只有匹配结果为true时,才会触发RHS部分的执行。本章节我们会针对LHS部分学习几个新的用法。</p><h4 id="6-4-1-复合值限制in-x2F-not-in"><a href="#6-4-1-复合值限制in-x2F-not-in" class="headerlink" title="6.4.1 复合值限制in/not in"></a>6.4.1 复合值限制in/not in</h4><p>复合值限制是指超过一种匹配值的限制条件,类似于SQL语句中的in关键字。Drools规则体中的LHS部分可以使用in或者not in进行复合值的匹配。具体语法结构如下:</p><p><strong>Object(field in (比较值1,比较值2…))</strong></p><p>举例:</p><pre class="line-numbers language-none"><code class="language-none">$s:Student(name in ("张三","李四","王五"))$s:Student(name not in ("张三","李四","王五"))<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre><h4 id="6-4-2-条件元素eval"><a href="#6-4-2-条件元素eval" class="headerlink" title="6.4.2 条件元素eval"></a>6.4.2 条件元素eval</h4><p>eval用于规则体的LHS部分,并返回一个Boolean类型的值。语法结构如下:</p><p><strong>eval(表达式)</strong></p><p>举例:</p><pre class="line-numbers language-none"><code class="language-none">eval(true)eval(false)eval(1 == 1)<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre><h4 id="6-4-3-条件元素not"><a href="#6-4-3-条件元素not" class="headerlink" title="6.4.3 条件元素not"></a>6.4.3 条件元素not</h4><p>not用于判断Working Memory中是否存在某个Fact对象,如果不存在则返回true,如果存在则返回false。语法结构如下:</p><p><strong>not Object(可选属性约束)</strong></p><p>举例:</p><pre class="line-numbers language-none"><code class="language-none">not Student()not Student(age < 10)<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre><h4 id="6-4-4-条件元素exists"><a href="#6-4-4-条件元素exists" class="headerlink" title="6.4.4 条件元素exists"></a>6.4.4 条件元素exists</h4><p>exists的作用与not相反,用于判断Working Memory中是否存在某个Fact对象,如果存在则返回true,不存在则返回false。语法结构如下:</p><p><strong>exists Object(可选属性约束)</strong></p><p>举例:</p><pre class="line-numbers language-none"><code class="language-none">exists Student()exists Student(age < 10 && name != null)<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre><p>可能有人会有疑问,我们前面在LHS部分进行条件编写时并没有使用exists也可以达到判断Working Memory中是否存在某个符合条件的Fact元素的目的,那么我们使用exists还有什么意义?</p><p>两者的区别:当向Working Memory中加入多个满足条件的Fact对象时,使用了exists的规则执行一次,不使用exists的规则会执行多次。</p><p>例如:</p><p>规则文件(只有规则体):</p><pre class="line-numbers language-none"><code class="language-none">rule "使用exists的规则" when exists Student() then System.out.println("规则:使用exists的规则触发");endrule "没有使用exists的规则" when Student() then System.out.println("规则:没有使用exists的规则触发");end<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>Java代码:</p><pre class="line-numbers language-none"><code class="language-none">kieSession.insert(new Student());kieSession.insert(new Student());kieSession.fireAllRules();<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre><p>上面第一个规则只会执行一次,因为Working Memory中存在两个满足条件的Fact对象,第二个规则会执行两次。</p><h4 id="6-4-5-规则继承"><a href="#6-4-5-规则继承" class="headerlink" title="6.4.5 规则继承"></a>6.4.5 规则继承</h4><p>规则之间可以使用extends关键字进行规则条件部分的继承,类似于java类之间的继承。<br><strong>注意:</strong>用了继承,rule中变量名中的变量保不能重复,比如rule_1中是$s,rule_2中也是$s就会编译异常</p><p>例如:</p><pre class="line-numbers language-none"><code class="language-none">rule "rule_1" when Student(age > 10) then System.out.println("规则:rule_1触发");endrule "rule_2" extends "rule_1" //继承上面的规则 when /* 此处的条件虽然只写了一个,但是从上面的规则继承了一个条件, 所以当前规则存在两个条件,即Student(age < 20)和Student(age > 10) */ Student(age < 20) then System.out.println("规则:rule_2触发");end<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h3 id="6-5-RHS加强"><a href="#6-5-RHS加强" class="headerlink" title="6.5 RHS加强"></a>6.5 RHS加强</h3><p>RHS部分是规则体的重要组成部分,当LHS部分的条件匹配成功后,对应的RHS部分就会触发执行。一般在RHS部分中需要进行业务处理。</p><p>在RHS部分Drools为我们提供了一个内置对象,名称就是drools。本小节我们来介绍几个drools对象提供的方法。</p><h4 id="6-5-1-halt"><a href="#6-5-1-halt" class="headerlink" title="6.5.1 halt"></a>6.5.1 halt</h4><p>halt方法的作用是<strong>立即终止后面所有规则的执行</strong>。</p><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">package</span> <span class="token namespace">testhalt</span>rule <span class="token string">"rule_halt_1"</span> when then <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"规则:rule_halt_1触发"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> drools<span class="token punctuation">.</span><span class="token function">halt</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//立即终止后面所有规则执行</span>end<span class="token comment">//当前规则并不会触发,因为上面的规则调用了halt方法导致后面所有规则都不会执行</span>rule <span class="token string">"rule_halt_2"</span> when then <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"规则:rule_halt_2触发"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>end<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h4 id="6-5-2-getWorkingMemory"><a href="#6-5-2-getWorkingMemory" class="headerlink" title="6.5.2 getWorkingMemory"></a>6.5.2 getWorkingMemory</h4><p>getWorkingMemory方法的作用是返回工作内存对象。</p><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">package</span> <span class="token namespace">testgetWorkingMemory</span>rule <span class="token string">"rule_getWorkingMemory"</span> when then <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>drools<span class="token punctuation">.</span><span class="token function">getWorkingMemory</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>end<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h4 id="6-5-3-getRule"><a href="#6-5-3-getRule" class="headerlink" title="6.5.3 getRule"></a>6.5.3 getRule</h4><p>getRule方法的作用是返回规则对象。</p><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">package</span> <span class="token namespace">testgetRule</span>rule <span class="token string">"rule_getRule"</span> when then <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>drools<span class="token punctuation">.</span><span class="token function">getRule</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>end<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h3 id="6-6-规则文件编码规范(重要)"><a href="#6-6-规则文件编码规范(重要)" class="headerlink" title="6.6 规则文件编码规范(重要)"></a>6.6 规则文件编码规范(重要)</h3><p>我们在进行drl类型的规则文件编写时尽量遵循如下规范:</p><ul><li>所有的规则文件(.drl)应统一放在一个规定的文件夹中,如:/rules文件夹</li><li>书写的每个规则应尽量加上注释。注释要清晰明了,言简意赅</li><li>同一类型的对象尽量放在一个规则文件中,如所有Student类型的对象尽量放在一个规则文件中</li><li>规则结果部分(RHS)尽量不要有条件语句,如if(…),尽量不要有复杂的逻辑和深层次的嵌套语句</li><li>每个规则最好都加上salience属性,明确执行顺序</li><li>Drools默认dialect为”Java”,尽量避免使用dialect “mvel”</li></ul><h2 id="7-Spring整合Drools"><a href="#7-Spring整合Drools" class="headerlink" title="7. Spring整合Drools"></a>7. Spring整合Drools</h2><h3 id="7-1-Spring简单整合Drools"><a href="#7-1-Spring简单整合Drools" class="headerlink" title="7.1 Spring简单整合Drools"></a>7.1 Spring简单整合Drools</h3><p>在项目中使用Drools时往往会跟Spring整合来使用。具体整合步骤如下:</p><p>第一步:创建maven工程drools_spring并配置pom.xml</p><pre class="line-numbers language-xml" data-language="xml"><code class="language-xml"><span class="token prolog"><?xml version="1.0" encoding="UTF-8"?></span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>project</span> <span class="token attr-name">xmlns</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>http://maven.apache.org/POM/4.0.0<span class="token punctuation">"</span></span> <span class="token attr-name"><span class="token namespace">xmlns:</span>xsi</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>http://www.w3.org/2001/XMLSchema-instance<span class="token punctuation">"</span></span> <span class="token attr-name"><span class="token namespace">xsi:</span>schemaLocation</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>modelVersion</span><span class="token punctuation">></span></span>4.0.0<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>modelVersion</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>com.itheima<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>drools_spring<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>1.0-SNAPSHOT<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>properties</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>drools.version</span><span class="token punctuation">></span></span>7.10.0.Final<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>drools.version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>spring.version</span><span class="token punctuation">></span></span>5.0.5.RELEASE<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>spring.version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>properties</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependencies</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.drools<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>drools-compiler<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>${drools.version}<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>junit<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>junit<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>4.12<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.kie<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>kie-spring<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>${drools.version}<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token comment"><!--注意:此处必须排除传递过来的依赖,否则会跟我们自己导入的Spring jar包产生冲突--></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>exclusions</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>exclusion</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-tx<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>exclusion</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>exclusion</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-beans<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>exclusion</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>exclusion</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-core<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>exclusion</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>exclusion</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-context<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>exclusion</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>exclusions</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-context<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>${spring.version}<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-context-support<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>${spring.version}<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-test<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>${spring.version}<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-tx<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>${spring.version}<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependencies</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>project</span><span class="token punctuation">></span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>第二步:创建规则目录/resources/rules,中rules目录中创建规则文件helloworld.drl</p><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">package</span> <span class="token namespace">helloworld</span>rule <span class="token string">"rule_helloworld"</span> when <span class="token function">eval</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span> then <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"规则:rule_helloworld触发..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>end<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>第三步:创建Spring配置文件/resources/spring.xml</p><pre class="line-numbers language-xml" data-language="xml"><code class="language-xml"><span class="token prolog"><?xml version="1.0" encoding="UTF-8"?></span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>beans</span> <span class="token attr-name">xmlns</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>http://www.springframework.org/schema/beans<span class="token punctuation">"</span></span> <span class="token attr-name"><span class="token namespace">xmlns:</span>xsi</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>http://www.w3.org/2001/XMLSchema-instance<span class="token punctuation">"</span></span> <span class="token attr-name"><span class="token namespace">xmlns:</span>kie</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>http://drools.org/schema/kie-spring<span class="token punctuation">"</span></span> <span class="token attr-name"><span class="token namespace">xsi:</span>schemaLocation</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://drools.org/schema/kie-spring http://drools.org/schema/kie-spring.xsd<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span><span class="token namespace">kie:</span>kmodule</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>kmodule<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span><span class="token namespace">kie:</span>kbase</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>kbase<span class="token punctuation">"</span></span> <span class="token attr-name">packages</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>rules<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span><span class="token namespace">kie:</span>ksession</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>ksession<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span><span class="token namespace">kie:</span>ksession</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span><span class="token namespace">kie:</span>kbase</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span><span class="token namespace">kie:</span>kmodule</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>bean</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>org.kie.spring.annotations.KModuleAnnotationPostProcessor<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>bean</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>beans</span><span class="token punctuation">></span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>第四步:编写单元测试类</p><pre class="line-numbers language-none"><code class="language-none">package com.itheima.test;import org.junit.Test;import org.junit.runner.RunWith;import org.kie.api.KieBase;import org.kie.api.cdi.KBase;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(locations = "classpath:spring.xml")public class DroolsSpringTest { @KBase("kbase") private KieBase kieBase;//注入KieBase对象 @Test public void test1(){ KieSession kieSession = kieBase.newKieSession(); kieSession.fireAllRules(); kieSession.dispose(); }}<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h3 id="7-2-Spring整合Drools-web"><a href="#7-2-Spring整合Drools-web" class="headerlink" title="7.2 Spring整合Drools+web"></a>7.2 Spring整合Drools+web</h3><p>本小节我们来进行Drools和Spring Web的整合。具体操作步骤如下:</p><p>第一步:创建maven的war工程drools_springweb并在pom.xml文件中导入相关maven坐标</p><pre class="line-numbers language-xml" data-language="xml"><code class="language-xml"><span class="token prolog"><?xml version="1.0" encoding="UTF-8"?></span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>project</span> <span class="token attr-name">xmlns</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>http://maven.apache.org/POM/4.0.0<span class="token punctuation">"</span></span> <span class="token attr-name"><span class="token namespace">xmlns:</span>xsi</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>http://www.w3.org/2001/XMLSchema-instance<span class="token punctuation">"</span></span> <span class="token attr-name"><span class="token namespace">xsi:</span>schemaLocation</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>modelVersion</span><span class="token punctuation">></span></span>4.0.0<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>modelVersion</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>com.itheima<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>drools_springweb<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>1.0-SNAPSHOT<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>packaging</span><span class="token punctuation">></span></span>war<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>packaging</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>properties</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>project.build.sourceEncoding</span><span class="token punctuation">></span></span>UTF-8<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>project.build.sourceEncoding</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>maven.compiler.source</span><span class="token punctuation">></span></span>1.8<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>maven.compiler.source</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>maven.compiler.target</span><span class="token punctuation">></span></span>1.8<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>maven.compiler.target</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>drools.version</span><span class="token punctuation">></span></span>7.10.0.Final<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>drools.version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>spring.version</span><span class="token punctuation">></span></span>5.0.5.RELEASE<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>spring.version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>properties</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependencies</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.drools<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>drools-compiler<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>${drools.version}<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>junit<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>junit<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>4.12<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.kie<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>kie-spring<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>${drools.version}<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token comment"><!--注意:此处必须排除传递过来的依赖,否则会跟我们自己导入的Spring jar包产生冲突--></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>exclusions</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>exclusion</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-tx<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>exclusion</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>exclusion</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-beans<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>exclusion</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>exclusion</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-core<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>exclusion</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>exclusion</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-context<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>exclusion</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>exclusions</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-context<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>${spring.version}<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-context-support<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>${spring.version}<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-test<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>${spring.version}<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-tx<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>${spring.version}<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-web<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>${spring.version}<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-webmvc<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>${spring.version}<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependencies</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>build</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>plugins</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>plugin</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.apache.tomcat.maven<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>tomcat7-maven-plugin<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>2.2<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> 自己加的版本号,不加的话,会报错 <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>configuration</span><span class="token punctuation">></span></span> <span class="token comment"><!-- 指定端口 --></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>port</span><span class="token punctuation">></span></span>80<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>port</span><span class="token punctuation">></span></span> <span class="token comment"><!-- 请求路径 --></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>path</span><span class="token punctuation">></span></span>/<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>path</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>configuration</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>plugin</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>plugins</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>build</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>project</span><span class="token punctuation">></span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>第二步:配置web.xml</p><pre class="line-numbers language-xml" data-language="xml"><code class="language-xml"><span class="token doctype"><span class="token punctuation"><!</span><span class="token doctype-tag">DOCTYPE</span> <span class="token name">web-app</span> <span class="token name">PUBLIC</span> <span class="token string">"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"</span> <span class="token string">"http://java.sun.com/dtd/web-app_2_3.dtd"</span> <span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>web-app</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>display-name</span><span class="token punctuation">></span></span>Archetype Created Web Application<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>display-name</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>servlet</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>servlet-name</span><span class="token punctuation">></span></span>springmvc<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>servlet-name</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>servlet-class</span><span class="token punctuation">></span></span>org.springframework.web.servlet.DispatcherServlet<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>servlet-class</span><span class="token punctuation">></span></span> <span class="token comment"><!-- 指定加载的配置文件 ,通过参数contextConfigLocation加载 --></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>init-param</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>param-name</span><span class="token punctuation">></span></span>contextConfigLocation<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>param-name</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>param-value</span><span class="token punctuation">></span></span>classpath:springmvc.xml<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>param-value</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>init-param</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>load-on-startup</span><span class="token punctuation">></span></span>1<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>load-on-startup</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>servlet</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>servlet-mapping</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>servlet-name</span><span class="token punctuation">></span></span>springmvc<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>servlet-name</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>url-pattern</span><span class="token punctuation">></span></span>*.do<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>url-pattern</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>servlet-mapping</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>web-app</span><span class="token punctuation">></span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>第三步:创建/resources/springmvc.xml文件</p><pre class="line-numbers language-xml" data-language="xml"><code class="language-xml"><span class="token prolog"><?xml version="1.0" encoding="UTF-8"?></span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>beans</span> <span class="token attr-name">xmlns</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>http://www.springframework.org/schema/beans<span class="token punctuation">"</span></span> <span class="token attr-name"><span class="token namespace">xmlns:</span>xsi</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>http://www.w3.org/2001/XMLSchema-instance<span class="token punctuation">"</span></span> <span class="token attr-name"><span class="token namespace">xmlns:</span>context</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>http://www.springframework.org/schema/context<span class="token punctuation">"</span></span> <span class="token attr-name"><span class="token namespace">xmlns:</span>mvc</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>http://www.springframework.org/schema/mvc<span class="token punctuation">"</span></span> <span class="token attr-name"><span class="token namespace">xmlns:</span>kie</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>http://drools.org/schema/kie-spring<span class="token punctuation">"</span></span> <span class="token attr-name"><span class="token namespace">xsi:</span>schemaLocation</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://drools.org/schema/kie-spring http://drools.org/schema/kie-spring.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span><span class="token namespace">kie:</span>kmodule</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>kmodule<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span><span class="token namespace">kie:</span>kbase</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>kbase<span class="token punctuation">"</span></span> <span class="token attr-name">packages</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>rules<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span><span class="token namespace">kie:</span>ksession</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>ksession<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span><span class="token namespace">kie:</span>ksession</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span><span class="token namespace">kie:</span>kbase</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span><span class="token namespace">kie:</span>kmodule</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>bean</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>org.kie.spring.annotations.KModuleAnnotationPostProcessor<span class="token punctuation">"</span></span><span class="token punctuation">/></span></span> <span class="token comment"><!--spring批量扫描--></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span><span class="token namespace">context:</span>component-scan</span> <span class="token attr-name">base-package</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>com.itheima<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span><span class="token namespace">context:</span>annotation-config</span><span class="token punctuation">/></span></span> <span class="token comment"><!--springMVC注解驱动--></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span><span class="token namespace">mvc:</span>annotation-driven</span><span class="token punctuation">/></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>beans</span><span class="token punctuation">></span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>第四步:创建规则文件/resources/rules/helloworld.drl</p><pre class="line-numbers language-none"><code class="language-none">package helloworldrule "rule_helloworld" when eval(true) then System.out.println("规则:rule_helloworld触发...");end<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>第五步:创建RuleService</p><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">package</span> <span class="token namespace">com<span class="token punctuation">.</span>itheima<span class="token punctuation">.</span>service</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>kie<span class="token punctuation">.</span>api<span class="token punctuation">.</span></span><span class="token class-name">KieBase</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>kie<span class="token punctuation">.</span>api<span class="token punctuation">.</span>cdi<span class="token punctuation">.</span></span><span class="token class-name">KBase</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>kie<span class="token punctuation">.</span>api<span class="token punctuation">.</span>runtime<span class="token punctuation">.</span></span><span class="token class-name">KieSession</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>stereotype<span class="token punctuation">.</span></span><span class="token class-name">Service</span><span class="token punctuation">;</span><span class="token annotation punctuation">@Service</span><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">RuleService</span> <span class="token punctuation">{</span> <span class="token annotation punctuation">@KBase</span><span class="token punctuation">(</span><span class="token string">"kbase"</span><span class="token punctuation">)</span> <span class="token keyword">private</span> <span class="token class-name">KieBase</span> kieBase<span class="token punctuation">;</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">rule</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token class-name">KieSession</span> kieSession <span class="token operator">=</span> kieBase<span class="token punctuation">.</span><span class="token function">newKieSession</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> kieSession<span class="token punctuation">.</span><span class="token function">fireAllRules</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> kieSession<span class="token punctuation">.</span><span class="token function">dispose</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>第六步:创建HelloController</p><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">package</span> <span class="token namespace">com<span class="token punctuation">.</span>itheima<span class="token punctuation">.</span>controller</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">com<span class="token punctuation">.</span>itheima<span class="token punctuation">.</span>service<span class="token punctuation">.</span></span><span class="token class-name">RuleService</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>beans<span class="token punctuation">.</span>factory<span class="token punctuation">.</span>annotation<span class="token punctuation">.</span></span><span class="token class-name">Autowired</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>web<span class="token punctuation">.</span>bind<span class="token punctuation">.</span>annotation<span class="token punctuation">.</span></span><span class="token class-name">RequestMapping</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>web<span class="token punctuation">.</span>bind<span class="token punctuation">.</span>annotation<span class="token punctuation">.</span></span><span class="token class-name">RestController</span><span class="token punctuation">;</span><span class="token annotation punctuation">@RestController</span><span class="token annotation punctuation">@RequestMapping</span><span class="token punctuation">(</span><span class="token string">"/hello"</span><span class="token punctuation">)</span><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">HelloController</span> <span class="token punctuation">{</span> <span class="token annotation punctuation">@Autowired</span> <span class="token keyword">private</span> <span class="token class-name">RuleService</span> ruleService<span class="token punctuation">;</span> <span class="token annotation punctuation">@RequestMapping</span><span class="token punctuation">(</span><span class="token string">"/rule"</span><span class="token punctuation">)</span> <span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">rule</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> ruleService<span class="token punctuation">.</span><span class="token function">rule</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token string">"OK"</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h3 id="7-3-Spring-Boot整合Drools"><a href="#7-3-Spring-Boot整合Drools" class="headerlink" title="7.3 Spring Boot整合Drools"></a>7.3 Spring Boot整合Drools</h3><p>目前在企业开发中Spring Boot已经成为主流,本小节我们来进行Spring Boot整合Drools。具体操作步骤:</p><p>第一步:创建maven工程drools_springboot并配置pom.xml</p><pre class="line-numbers language-xml" data-language="xml"><code class="language-xml"><span class="token prolog"><?xml version="1.0" encoding="UTF-8"?></span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>project</span> <span class="token attr-name">xmlns</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>http://maven.apache.org/POM/4.0.0<span class="token punctuation">"</span></span> <span class="token attr-name"><span class="token namespace">xmlns:</span>xsi</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>http://www.w3.org/2001/XMLSchema-instance<span class="token punctuation">"</span></span> <span class="token attr-name"><span class="token namespace">xsi:</span>schemaLocation</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>parent</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-boot-starters<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>2.0.6.RELEASE<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>parent</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>modelVersion</span><span class="token punctuation">></span></span>4.0.0<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>modelVersion</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>com.itheima<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>drools_springboot<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>1.0-SNAPSHOT<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependencies</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-boot-starter-web<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-boot-starter-aop<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-boot-starter-test<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>commons-lang<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>commons-lang<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>2.6<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token comment"><!--drools规则引擎--></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.drools<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>drools-core<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>7.6.0.Final<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.drools<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>drools-compiler<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>7.6.0.Final<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.drools<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>drools-templates<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>7.6.0.Final<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.kie<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>kie-api<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>7.6.0.Final<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.kie<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>kie-spring<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>exclusions</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>exclusion</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-tx<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>exclusion</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>exclusion</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-beans<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>exclusion</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>exclusion</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-core<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>exclusion</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>exclusion</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-context<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>exclusion</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>exclusions</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>7.6.0.Final<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependencies</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>build</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>finalName</span><span class="token punctuation">></span></span>${project.artifactId}<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>finalName</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>resources</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>resource</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>directory</span><span class="token punctuation">></span></span>src/main/java<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>directory</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>includes</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>include</span><span class="token punctuation">></span></span>**/*.xml<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>include</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>includes</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>filtering</span><span class="token punctuation">></span></span>false<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>filtering</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>resource</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>resource</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>directory</span><span class="token punctuation">></span></span>src/main/resources<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>directory</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>includes</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>include</span><span class="token punctuation">></span></span>**/*.*<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>include</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>includes</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>filtering</span><span class="token punctuation">></span></span>false<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>filtering</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>resource</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>resources</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>plugins</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>plugin</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.apache.maven.plugins<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>maven-compiler-plugin<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>2.3.2<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>configuration</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>source</span><span class="token punctuation">></span></span>1.8<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>source</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>target</span><span class="token punctuation">></span></span>1.8<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>target</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>configuration</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>plugin</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>plugins</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>build</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>project</span><span class="token punctuation">></span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>第二步:创建/resources/application.yml文件</p><pre class="line-numbers language-none"><code class="language-none">server: port: 8080spring: application: name: drools_springboot<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>第三步:创建规则文件/resources/rules/helloworld.drl</p><pre class="line-numbers language-none"><code class="language-none">package helloworldrule "rule_helloworld" when eval(true) then System.out.println("规则:rule_helloworld触发...");end<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>第四步:编写配置类DroolsConfig</p><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">package</span> <span class="token namespace">com<span class="token punctuation">.</span>itheima<span class="token punctuation">.</span>drools<span class="token punctuation">.</span>config</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>kie<span class="token punctuation">.</span>api<span class="token punctuation">.</span></span><span class="token class-name">KieBase</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>kie<span class="token punctuation">.</span>api<span class="token punctuation">.</span></span><span class="token class-name">KieServices</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>kie<span class="token punctuation">.</span>api<span class="token punctuation">.</span>builder<span class="token punctuation">.</span></span><span class="token class-name">KieBuilder</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>kie<span class="token punctuation">.</span>api<span class="token punctuation">.</span>builder<span class="token punctuation">.</span></span><span class="token class-name">KieFileSystem</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>kie<span class="token punctuation">.</span>api<span class="token punctuation">.</span>builder<span class="token punctuation">.</span></span><span class="token class-name">KieRepository</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>kie<span class="token punctuation">.</span>api<span class="token punctuation">.</span>runtime<span class="token punctuation">.</span></span><span class="token class-name">KieContainer</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>kie<span class="token punctuation">.</span>api<span class="token punctuation">.</span>runtime<span class="token punctuation">.</span></span><span class="token class-name">KieSession</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>kie<span class="token punctuation">.</span>internal<span class="token punctuation">.</span>io<span class="token punctuation">.</span></span><span class="token class-name">ResourceFactory</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>kie<span class="token punctuation">.</span>spring<span class="token punctuation">.</span></span><span class="token class-name">KModuleBeanFactoryPostProcessor</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>boot<span class="token punctuation">.</span>autoconfigure<span class="token punctuation">.</span>condition<span class="token punctuation">.</span></span><span class="token class-name">ConditionalOnMissingBean</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>context<span class="token punctuation">.</span>annotation<span class="token punctuation">.</span></span><span class="token class-name">Bean</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>context<span class="token punctuation">.</span>annotation<span class="token punctuation">.</span></span><span class="token class-name">Configuration</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>core<span class="token punctuation">.</span>io<span class="token punctuation">.</span>support<span class="token punctuation">.</span></span><span class="token class-name">PathMatchingResourcePatternResolver</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>core<span class="token punctuation">.</span>io<span class="token punctuation">.</span>support<span class="token punctuation">.</span></span><span class="token class-name">ResourcePatternResolver</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>core<span class="token punctuation">.</span>io<span class="token punctuation">.</span></span><span class="token class-name">Resource</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">java<span class="token punctuation">.</span>io<span class="token punctuation">.</span></span><span class="token class-name">IOException</span><span class="token punctuation">;</span><span class="token comment">/** * 规则引擎配置类 */</span><span class="token annotation punctuation">@Configuration</span><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">DroolsConfig</span> <span class="token punctuation">{</span> <span class="token comment">//指定规则文件存放的目录</span> <span class="token keyword">private</span> <span class="token keyword">static</span> <span class="token keyword">final</span> <span class="token class-name">String</span> RULES_PATH <span class="token operator">=</span> <span class="token string">"rules/"</span><span class="token punctuation">;</span> <span class="token keyword">private</span> <span class="token keyword">final</span> <span class="token class-name">KieServices</span> kieServices <span class="token operator">=</span> <span class="token class-name">KieServices<span class="token punctuation">.</span>Factory</span><span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token annotation punctuation">@Bean</span> <span class="token annotation punctuation">@ConditionalOnMissingBean</span> <span class="token keyword">public</span> <span class="token class-name">KieFileSystem</span> <span class="token function">kieFileSystem</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">IOException</span> <span class="token punctuation">{</span> <span class="token class-name">KieFileSystem</span> kieFileSystem <span class="token operator">=</span> kieServices<span class="token punctuation">.</span><span class="token function">newKieFileSystem</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">ResourcePatternResolver</span> resourcePatternResolver <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">PathMatchingResourcePatternResolver</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">Resource</span><span class="token punctuation">[</span><span class="token punctuation">]</span> files <span class="token operator">=</span> resourcePatternResolver<span class="token punctuation">.</span><span class="token function">getResources</span><span class="token punctuation">(</span><span class="token string">"classpath*:"</span> <span class="token operator">+</span> RULES_PATH <span class="token operator">+</span> <span class="token string">"*.*"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">String</span> path <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token class-name">Resource</span> file <span class="token operator">:</span> files<span class="token punctuation">)</span> <span class="token punctuation">{</span> path <span class="token operator">=</span> RULES_PATH <span class="token operator">+</span> file<span class="token punctuation">.</span><span class="token function">getFilename</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> kieFileSystem<span class="token punctuation">.</span><span class="token function">write</span><span class="token punctuation">(</span><span class="token class-name">ResourceFactory</span><span class="token punctuation">.</span><span class="token function">newClassPathResource</span><span class="token punctuation">(</span>path<span class="token punctuation">,</span> <span class="token string">"UTF-8"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> kieFileSystem<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token annotation punctuation">@Bean</span> <span class="token annotation punctuation">@ConditionalOnMissingBean</span> <span class="token keyword">public</span> <span class="token class-name">KieContainer</span> <span class="token function">kieContainer</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">IOException</span> <span class="token punctuation">{</span> <span class="token class-name">KieRepository</span> kieRepository <span class="token operator">=</span> kieServices<span class="token punctuation">.</span><span class="token function">getRepository</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> kieRepository<span class="token punctuation">.</span><span class="token function">addKieModule</span><span class="token punctuation">(</span>kieRepository<span class="token operator">::</span><span class="token function">getDefaultReleaseId</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">KieBuilder</span> kieBuilder <span class="token operator">=</span> kieServices<span class="token punctuation">.</span><span class="token function">newKieBuilder</span><span class="token punctuation">(</span><span class="token function">kieFileSystem</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> kieBuilder<span class="token punctuation">.</span><span class="token function">buildAll</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> kieServices<span class="token punctuation">.</span><span class="token function">newKieContainer</span><span class="token punctuation">(</span>kieRepository<span class="token punctuation">.</span><span class="token function">getDefaultReleaseId</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token annotation punctuation">@Bean</span> <span class="token annotation punctuation">@ConditionalOnMissingBean</span> <span class="token keyword">public</span> <span class="token class-name">KieBase</span> <span class="token function">kieBase</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">IOException</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token function">kieContainer</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getKieBase</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token annotation punctuation">@Bean</span> <span class="token annotation punctuation">@ConditionalOnMissingBean</span> <span class="token keyword">public</span> <span class="token class-name">KModuleBeanFactoryPostProcessor</span> <span class="token function">kiePostProcessor</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">KModuleBeanFactoryPostProcessor</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>第五步:创建RuleService类</p><pre class="line-numbers language-none"><code class="language-none">package com.itheima.drools.service;import org.kie.api.KieBase;import org.kie.api.runtime.KieSession;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;@Servicepublic class RuleService { @Autowired private KieBase kieBase; public void rule(){ KieSession kieSession = kieBase.newKieSession(); kieSession.fireAllRules(); kieSession.dispose(); }}<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>第六步:创建HelloController类</p><pre class="line-numbers language-none"><code class="language-none">package com.itheima.drools.controller;import com.itheima.drools.service.RuleService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;@RestController@RequestMapping("/hello")public class HelloController { @Autowired private RuleService ruleService; @RequestMapping("/rule") public String rule(){ ruleService.rule(); return "OK"; }}<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>第七步:创建启动类DroolsApplication</p><pre class="line-numbers language-none"><code class="language-none">package com.itheima.drools;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplicationpublic class DroolsApplication { public static void main(String[] args) { SpringApplication.run(DroolsApplication.class,args); }}<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>第八步:启动服务,访问<a href="http://localhost:8080/hello/rule">http://localhost:8080/hello/rule</a></p><h2 id="8-WorkBench"><a href="#8-WorkBench" class="headerlink" title="8. WorkBench"></a>8. WorkBench</h2><h3 id="8-1-WorkBench简介"><a href="#8-1-WorkBench简介" class="headerlink" title="8.1 WorkBench简介"></a>8.1 WorkBench简介</h3><p>WorkBench是KIE组件中的元素,也称为KIE-WB,是Drools-WB与JBPM-WB的结合体。它是一个<strong>可视化的规则编辑器</strong>。WorkBench其实就是一个war包,安装到tomcat中就可以运行。使用WorkBench可以在浏览器中创建数据对象、创建规则文件、创建测试场景并将规则部署到maven仓库供其他应用使用。</p><p>下载地址:<a href="https://download.jboss.org/drools/release/7.6.0.Final/kie-drools-wb-7.6.0.Final-tomcat8.war">https://download.jboss.org/drools/release/7.6.0.Final/kie-drools-wb-7.6.0.Final-tomcat8.war</a></p><p>注意:下载的war包需要安装到tomcat8中。</p><img src="https://gitee.com/EverSpring007/picbed/raw/master/20160726000447542" alt="img" style="zoom: 50%;" /><h3 id="8-2-安装方式"><a href="#8-2-安装方式" class="headerlink" title="8.2 安装方式"></a>8.2 安装方式</h3><h4 id="8-2-1自己安装"><a href="#8-2-1自己安装" class="headerlink" title="8.2.1自己安装"></a>8.2.1自己安装</h4><p>软件安装时经常会涉及到软件版本兼容性的问题,所以需要明确各个软件的使用版本。</p><p>本课程使用的软件环境如下:</p><ul><li>操作系统:Windows 10 64位</li><li>JDK版本:1.8</li><li>maven版本:3.5.4</li><li>Tomcat版本:8.5</li></ul><p>具体安装步骤:</p><p>第一步:配置Tomcat的环境变量CATALINA_HOME,对应的值为Tomcat安装目录</p><p>第二步:在Tomcat的bin目录下创建setenv.bat文件,内容如下:</p><pre class="line-numbers language-none"><code class="language-none">CATALINA_OPTS="-Xmx512M \ -Djava.security.auth.login.config=$CATALINA_HOME/webapps/kie-drools-wb/WEB-INF/classes/login.config \ -Dorg.jboss.logging.provider=jdk"<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre><p>第三步:将下载的WorkBench的war包改名为kie-drools-wb.war并复制到Tomcat的webapps目录下</p><p>第四步:修改Tomcat下conf/tomcat-users.xml文件</p><pre class="line-numbers language-xml" data-language="xml"><code class="language-xml"><span class="token prolog"><?xml version='1.0' encoding='utf-8'?></span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>tomcat-users</span> <span class="token attr-name">xmlns</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>http://tomcat.apache.org/xml<span class="token punctuation">"</span></span> <span class="token attr-name"><span class="token namespace">xmlns:</span>xsi</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>http://www.w3.org/2001/XMLSchema-instance<span class="token punctuation">"</span></span> <span class="token attr-name"><span class="token namespace">xsi:</span>schemaLocation</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>http://tomcat.apache.org/xml tomcat-users.xsd<span class="token punctuation">"</span></span> <span class="token attr-name">version</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>1.0<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token comment"><!--定义admin角色--></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>role</span> <span class="token attr-name">rolename</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>admin<span class="token punctuation">"</span></span><span class="token punctuation">/></span></span> <span class="token comment"><!--定义一个用户,用户名为kie,密码为kie,对应的角色为admin角色--></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>user</span> <span class="token attr-name">username</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>kie<span class="token punctuation">"</span></span> <span class="token attr-name">password</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>kie<span class="token punctuation">"</span></span> <span class="token attr-name">roles</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>admin<span class="token punctuation">"</span></span><span class="token punctuation">/></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>tomcat-users</span><span class="token punctuation">></span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>第五步:下载以下三个jar包并复制到Tomcat的lib目录下</p><pre class="line-numbers language-none"><code class="language-none">kie-tomcat-integration-7.10.0.Final.jarjavax.security.jacc-api-1.5.jarslf4j-api-1.7.25.jar<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre><p>第六步:修改Tomcat的conf/server.xml文件,添加Valve标签,内容为:</p><pre class="line-numbers language-xml" data-language="xml"><code class="language-xml"><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>Valve</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>org.kie.integration.tomcat.JACCValve<span class="token punctuation">"</span></span><span class="token punctuation">/></span></span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>第七步:启动Tomcat并访问<a href="http://localhost:8080/kie-drools-wb%EF%BC%8C%E5%8F%AF%E4%BB%A5%E7%9C%8B%E5%88%B0WorkBench%E7%9A%84%E7%99%BB%E5%BD%95%E9%A1%B5%E9%9D%A2%E3%80%82%E4%BD%BF%E7%94%A8%E5%89%8D%E9%9D%A2%E5%9C%A8tomcat-users.xml%E6%96%87%E4%BB%B6%E4%B8%AD%E5%AE%9A%E4%B9%89%E7%9A%84%E7%94%A8%E6%88%B7%E8%BF%9B%E8%A1%8C%E7%99%BB%E5%BD%95%E5%8D%B3%E5%8F%AF">http://localhost:8080/kie-drools-wb,可以看到WorkBench的登录页面。使用前面在tomcat-users.xml文件中定义的用户进行登录即可</a></p><p>注意:这里我自己的是80端口,<a href="http://localhost/kie-drools-wb">http://localhost/kie-drools-wb</a></p><p><img src="/media/pictures/Drools.assets/12.png" alt="12"></p><p>登录成功后进入系统首页:</p><p><img src="/media/pictures/Drools.assets/13.png" alt="13"></p><h4 id="8-2-2-docker安装"><a href="#8-2-2-docker安装" class="headerlink" title="8.2.2 docker安装"></a>8.2.2 docker安装</h4><p>使用docker安装方便很多,docker镜像地址:<a href="https://hub.docker.com/r/jboss/drools-workbench-showcase">https://hub.docker.com/r/jboss/drools-workbench-showcase</a> 。<br>注意一下:有两个版本,drools-workbench-showcase和drools-workbench,它们的不同之处在于“drools-workbench-showcase”是官方配置好的“drools-workbench”,因而在“drools-workbench-showcase”中用户不用自己去注册,直接将账号拿来登录就可以了,而“drools-workbench”不是,它还得需要手动去注册账号,因而使用最多的也就是“drools-workbench-showcase”<br>第一步:选择对应的7.6.0版本</p><pre class="line-numbers language-shell" data-language="shell"><code class="language-shell">docker pull jboss/drools-workbench-showcase:7.6.0.Final<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>第二步:启动容器</p><pre class="line-numbers language-shell" data-language="shell"><code class="language-shell">$ docker run -p 10076:8080 -p 10077:8001 -d --name drools-workbench jboss/drools-workbench-showcase:7.6.0.Final<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>10076端口为控制台地址,10077为内置的git仓库端口<br>kie workbench内置了一个git仓库,创建的工程等内容就存储在仓库中的。为了安全,可以启动的时候指定volumn,挂载到host。git默认地址为$WORKING_DIR/.niogit,7.6.0版本指向的是/opt/jboss/wildfly/bin/.niogit。启动可以命令改为</p><pre class="line-numbers language-shell" data-language="shell"><code class="language-shell">$ docker cp 镜像id:/opt/jboss/wildfly/bin/.niogit /home/docker/drools-workbench$ docker run -p 10076:8080 -p 10077:8001 --user=$UID:$(id -g $USER) -v /home/docker/drools-workbench/.niogit:/opt/jboss/wildfly/bin/.niogit -d --name drools-workbench jboss/drools-workbench-showcase:7.6.0.Final<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre><p><strong>注意</strong>:要指定用户–user=$UID:$(id -g $USER),否则在启动时出现权限不足的问题<br>第三步:访问<a href="http://xxx:10076/drools-wb">http://xxx:10076/drools-wb</a><br>默认已有的用户和角色</p><table><thead><tr><th>USER</th><th>PASSWORD</th><th>ROLE</th></tr></thead><tbody><tr><td>admin</td><td>admin</td><td>admin,analyst,kiemgmt</td></tr><tr><td>krisv</td><td>krisv</td><td>admin,analyst</td></tr><tr><td>john</td><td>john</td><td>analyst,Accounting,PM</td></tr><tr><td>sales-rep</td><td>sales-rep</td><td>analyst,sales</td></tr><tr><td>katy</td><td>katy</td><td>analyst,HR</td></tr><tr><td>jack</td><td>jack</td><td>analyst,IT</td></tr><tr><td>第四步:</td><td></td><td></td></tr><tr><td>后面创建project,facts,drl文件和8.2一样</td><td></td><td></td></tr></tbody></table><h3 id="8-3-使用方式"><a href="#8-3-使用方式" class="headerlink" title="8.3 使用方式"></a>8.3 使用方式</h3><h4 id="8-3-1-创建空间、项目"><a href="#8-3-1-创建空间、项目" class="headerlink" title="8.3.1 创建空间、项目"></a>8.3.1 创建空间、项目</h4><p>WorkBench中存在空间和项目的概念。我们在使用WorkBench时首先需要创建空间(Space),在空间中创建项目,在项目中创建数据对象、规则文件等。</p><ul><li><p>创建空间</p><p>第一步:登录WorkBench后进行系统首页,点击首页中的Design区域进入项目列表页面:</p><p><img src="/media/pictures/Drools.assets/14.png" alt="14"></p><p>如果是第一次登录还没有创建项目则无法看到项目</p><p>第二步:点击左上角Spaces导航链接进入空间列表页面</p><p><img src="/media/pictures/Drools.assets/15.png" alt="15"></p><p>第三步:点击右上角Add Space按钮弹出创建添加空间窗口</p><p><img src="/media/pictures/Drools.assets/16.png" alt="16"></p><p>录入空间名称,点击Save按钮则完成空间的创建,如下图:</p><p><img src="/media/pictures/Drools.assets/17.png" alt="17"></p></li><li><p>创建项目</p><p>前面已经提到,我们在WorkBench中需要先创建空间,在空间中才能创建项目。上面我们已经创建了一个空间itheima,现在需要住此空间中创建项目。</p><p>第一步:点击itheima空间,进入此空间</p><p><img src="/media/pictures/Drools.assets/18.png" alt="18"></p><p>可以看到当前空间中还没有项目</p><p>第二步:点击Add Project按钮弹出添加项目窗口</p><p><img src="/media/pictures/Drools.assets/19.png" alt="19"></p><p>第三步:在添加项目窗口中录入项目名称(例如项目名称为pro1),点击Add按钮完成操作</p><p><img src="/media/pictures/Drools.assets/20.png" alt="20"></p><p>可以看到在完成项目创建后,系统直接跳转到了项目页面。要查看当前itheima空间中的所有项目,可以点击左上角itheima链接:</p><p><img src="/media/pictures/Drools.assets/21.png" alt="21"></p></li></ul><h4 id="8-3-2-创建数据对象"><a href="#8-3-2-创建数据对象" class="headerlink" title="8.3.2 创建数据对象"></a>8.3.2 创建数据对象</h4><p>数据对象其实就是JavaBean,一般都是在drl规则文件中使用进行规则匹配。</p><p>第一步:在itheima空间中点击pro1项目,进入此项目页面</p><p><img src="/media/pictures/Drools.assets/22.png" alt="22"></p><p>第二步:点击Create New Asset按钮选择“数据对象”</p><p><img src="/media/pictures/Drools.assets/23.png" alt="23"></p><p>第三步:在弹出的创建数据对象窗口中输入数据对象的名称,点击确定按钮完成操作</p><p><img src="/media/pictures/Drools.assets/24.png" alt="24"></p><p>操作完成后可以看到如下:</p><p><img src="/media/pictures/Drools.assets/25.png" alt="25"></p><p>第四步:点击“添加字段”按钮弹出新建字段窗口</p><p><img src="/media/pictures/Drools.assets/26.png" alt="26"></p><p>第五步:在新建字段窗口中录入字段Id(其实就是属性名),选择类型,点击创建按钮完成操作</p><p><img src="/media/pictures/Drools.assets/27.png" alt="27"></p><p>完成操作后可以看到刚才创建的字段:</p><p><img src="/media/pictures/Drools.assets/28.png" alt="28"></p><p>可以点击添加字段按钮继续创建其他字段:</p><p><img src="/media/pictures/Drools.assets/29.png" alt="29"></p><p>注意添加完字段后需要点击右上角保存按钮完成保存操作:</p><p><img src="/media/pictures/Drools.assets/32.png" alt="32"></p><p>点击源代码按钮可以查看刚才创建的Person对象源码:</p><p><img src="/media/pictures/Drools.assets/30.png" alt="30"></p><p>点击左上角pro1项目链接,可以看到当前pro1项目中已经创建的各种类型的对象:</p><p><img src="/media/pictures/Drools.assets/31.png" alt="31"></p><h4 id="8-3-3-创建DRL规则文件"><a href="#8-3-3-创建DRL规则文件" class="headerlink" title="8.3.3 创建DRL规则文件"></a>8.3.3 创建DRL规则文件</h4><p>第一步:在pro1项目页面点击右上角Create New Asset按钮,选择“DRL文件”,弹出创建DRL文件窗口</p><p><img src="/media/pictures/Drools.assets/33.png" alt="33"></p><p>第二步:在添加DRL文件窗口录入DRL文件名称,点击确定按钮完成操作</p><p><img src="/media/pictures/Drools.assets/34.png" alt="34"></p><p>第三步:上面点击确定按钮完成创建DRL文件后,页面会跳转到编辑DRL文件页面</p><p><img src="/media/pictures/Drools.assets/35.png" alt="35"></p><p>可以看到DRL规则文件页面分为两个部分:左侧为项目浏览视图、右侧为编辑区域,需要注意的是左侧默认展示的不是项目浏览视图,需要点击上面设置按钮,选择“资料库视图”和“显示为文件夹”,如下图所示:</p><p><img src="/media/pictures/Drools.assets/36.png" alt="36"></p><p>第四步:在编辑DRL文件页面右侧区域进行DRL文件的编写,点击右上角保存按钮完成保存操作,点击检验按钮进行规则文件语法检查</p><p><img src="/media/pictures/Drools.assets/37.png" alt="37"></p><p>点击左上角pro1项目回到项目页面,可以看到此项目下已经存在两个对象,即person.drl规则文件和Person类:</p><p><img src="/media/pictures/Drools.assets/38.png" alt="38"></p><h4 id="8-3-4-创建测试场景"><a href="#8-3-4-创建测试场景" class="headerlink" title="8.3.4 创建测试场景"></a>8.3.4 创建测试场景</h4><p>前面我们已经创建了Person数据对象和person规则文件,现在我们需要测试一下规则文件中的规则,可以通过创建测试场景来进行测试。</p><p>第一步:在项目页面点击Create New Asset按钮选择“测试场景”,弹出创建测试场景窗口</p><p><img src="/media/pictures/Drools.assets/39.png" alt="39"></p><p>第二步:在弹出的创建测试场景窗口中录入测试场景的名称,点击确定完成操作</p><p><img src="/media/pictures/Drools.assets/40.png" alt="40"></p><p>完成测试场景的创建后,页面会跳转到测试场景编辑页面,如下图:</p><p><img src="/media/pictures/Drools.assets/41.png" alt="41"></p><p>第三步:因为我们编写的规则文件中需要从工作内存中获取Person对象进行规则匹配,所以在测试场景中需要准备Person对象给工作内存,点击“GIVEN”按钮弹出新建数据录入窗口,选择Person类,输入框中输入事实名称(名称任意),如下图</p><p><img src="/media/pictures/Drools.assets/42.png" alt="42"></p><p>第四步:录入事实名称后点击后面的添加按钮,可以看到Person对象已经添加成功</p><p><img src="/media/pictures/Drools.assets/43.png" alt="43"></p><p>第五步:我们给工作内存提供的Person对象还需要设置age属性的值,点击“添加字段”按钮弹出窗口,选择age属性</p><p><img src="/media/pictures/Drools.assets/44.png" alt="44"></p><p>点击确定按钮后可以看到字段已经添加成功:</p><p><img src="/media/pictures/Drools.assets/45.png" alt="45"></p><p>第六步:点击age属性后面的编辑按钮,弹出字段值窗口</p><p><img src="/media/pictures/Drools.assets/image-20200113154817582.png" alt="image-20200113154817582"></p><p>第七步:在弹出的窗口中点击字面值按钮,重新回到测试场景页面,可以看到age后面出现输入框,可以为age属性设置值</p><p><img src="/media/pictures/Drools.assets/image-20200113155136957.png" alt="image-20200113155136957"></p><p>设置好age属性的值后点击保存按钮保存测试场景</p><p>第八步:点击右上角“运行测试场景”按钮进行测试</p><p><img src="/media/pictures/Drools.assets/image-20200113155332666.png" alt="image-20200113155332666"></p><p>测试成功后可以查看WorkBench部署的Tomcat控制台:</p><p><img src="/media/pictures/Drools.assets/image-20200113155819517.png" alt="image-20200113155819517"></p><h4 id="8-3-5-设置KieBase和KieSession"><a href="#8-3-5-设置KieBase和KieSession" class="headerlink" title="8.3.5 设置KieBase和KieSession"></a>8.3.5 设置KieBase和KieSession</h4><p>第一步:在pro1项目页面点击右上角Settings按钮进入设置页面</p><p><img src="/media/pictures/Drools.assets/image-20200113162923877.png" alt="image-20200113162923877"></p><p>第二步:在设置页面选择“知识库和会话”选项</p><p><img src="/media/pictures/Drools.assets/image-20200113163005061.png" alt="image-20200113163005061"></p><p>第三步:在弹出的知识库和会话页面点击“添加”按钮进行设置</p><p><img src="/media/pictures/Drools.assets/image-20200113163313305.png" alt="image-20200113163313305"></p><p><img src="/media/pictures/Drools.assets/image-20200113163344174.png" alt="image-20200113163344174"></p><p>第四步:设置完成后点击右上角保存按钮完成设置操作,可以通过左侧浏览视图点击kmodule.xml,查看文件内容</p><p>注意:出不来的话,要刷新一下。</p><p><img src="/media/pictures/Drools.assets/image-20200113163539676.png" alt="image-20200113163539676"></p><h4 id="8-3-6-编译、构建、部署"><a href="#8-3-6-编译、构建、部署" class="headerlink" title="8.3.6 编译、构建、部署"></a>8.3.6 编译、构建、部署</h4><p>前面我们已经在WorkBench中创建了一个空间itheima,并且在此空间中创建了一个项目pro1,在此项目中创建了数据文件、规则文件和测试场景,如下图:</p><p><img src="/media/pictures/Drools.assets/image-20200113160102668.png" alt="image-20200113160102668"></p><p>点击右上角“Compile”按钮可以对项目进行编译,点击“Bulid&Deploy”按钮进行构建和部署。</p><p>部署成功后可以在本地maven仓库中看到当前项目已经被打成jar包:</p><p><img src="/media/pictures/Drools.assets/image-20200113160728259.png" alt="image-20200113160728259"></p><p>将上面的jar包进行解压,可以看到我们创建的数据对象Person和规则文件person以及kmodule.xml都已经打到jar包中了。</p><h4 id="8-3-7-在项目中使用部署的规则"><a href="#8-3-7-在项目中使用部署的规则" class="headerlink" title="8.3.7 在项目中使用部署的规则"></a>8.3.7 在项目中使用部署的规则</h4><p>前面我们已经在WorkBench中创建了pro1项目,并且在pro1项目中创建了数据文件、规则文件等。最后我们将此项目打成jar包部署到了maven仓库中。本小节就需要在外部项目中使用我们定义的规则。</p><p>第一步:在IDEA中创建一个maven项目并在pom.xml文件中导入相关坐标</p><pre class="line-numbers language-none"><code class="language-none"><dependency> <groupId>org.drools</groupId> <artifactId>drools-compiler</artifactId> <version>7.10.0.Final</version></dependency><dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version></dependency><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>第二步:在项目中创建一个数据对象Person,需要和WorkBench中创建的Person包名、类名完全相同,属性也需要对应</p><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">package</span> <span class="token namespace">com<span class="token punctuation">.</span>itheima<span class="token punctuation">.</span>pro1</span><span class="token punctuation">;</span><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">Person</span> <span class="token keyword">implements</span> <span class="token class-name"><span class="token namespace">java<span class="token punctuation">.</span>io<span class="token punctuation">.</span></span>Serializable</span> <span class="token punctuation">{</span> <span class="token keyword">static</span> <span class="token keyword">final</span> <span class="token keyword">long</span> serialVersionUID <span class="token operator">=</span> <span class="token number">1L</span><span class="token punctuation">;</span> <span class="token keyword">private</span> <span class="token class-name"><span class="token namespace">java<span class="token punctuation">.</span>lang<span class="token punctuation">.</span></span>String</span> id<span class="token punctuation">;</span> <span class="token keyword">private</span> <span class="token class-name"><span class="token namespace">java<span class="token punctuation">.</span>lang<span class="token punctuation">.</span></span>String</span> name<span class="token punctuation">;</span> <span class="token keyword">private</span> <span class="token keyword">int</span> age<span class="token punctuation">;</span> <span class="token keyword">public</span> <span class="token class-name">Person</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token class-name"><span class="token namespace">java<span class="token punctuation">.</span>lang<span class="token punctuation">.</span></span>String</span> <span class="token function">getId</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>id<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setId</span><span class="token punctuation">(</span><span class="token class-name"><span class="token namespace">java<span class="token punctuation">.</span>lang<span class="token punctuation">.</span></span>String</span> id<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>id <span class="token operator">=</span> id<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token class-name"><span class="token namespace">java<span class="token punctuation">.</span>lang<span class="token punctuation">.</span></span>String</span> <span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setName</span><span class="token punctuation">(</span><span class="token class-name"><span class="token namespace">java<span class="token punctuation">.</span>lang<span class="token punctuation">.</span></span>String</span> name<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">int</span> <span class="token function">getAge</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>age<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setAge</span><span class="token punctuation">(</span><span class="token keyword">int</span> age<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>age <span class="token operator">=</span> age<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token class-name">Person</span><span class="token punctuation">(</span><span class="token class-name"><span class="token namespace">java<span class="token punctuation">.</span>lang<span class="token punctuation">.</span></span>String</span> id<span class="token punctuation">,</span> <span class="token class-name"><span class="token namespace">java<span class="token punctuation">.</span>lang<span class="token punctuation">.</span></span>String</span> name<span class="token punctuation">,</span> <span class="token keyword">int</span> age<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>id <span class="token operator">=</span> id<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>age <span class="token operator">=</span> age<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>第三步:编写单元测试,远程加载maven仓库中的jar包最终完成规则调用</p><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token annotation punctuation">@Test</span><span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">test1</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">Exception</span><span class="token punctuation">{</span> <span class="token comment">//通过此URL可以访问到maven仓库中的jar包</span> <span class="token comment">//URL地址构成:http://ip地址:Tomcat端口号/WorkBench工程名/maven2/坐标/版本号/xxx.jar</span> <span class="token class-name">String</span> url <span class="token operator">=</span> <span class="token string">"http://localhost:8080/kie-drools-wb/maven2/com/itheima/pro1/1.0.0/pro1-1.0.0.jar"</span><span class="token punctuation">;</span> <span class="token class-name">KieServices</span> kieServices <span class="token operator">=</span> <span class="token class-name">KieServices<span class="token punctuation">.</span>Factory</span><span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//通过Resource资源对象加载jar包</span> <span class="token class-name">UrlResource</span> resource <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token class-name">UrlResource</span><span class="token punctuation">)</span> kieServices<span class="token punctuation">.</span><span class="token function">getResources</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">newUrlResource</span><span class="token punctuation">(</span>url<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//通过Workbench提供的服务来访问maven仓库中的jar包资源,需要先进行Workbench的认证</span> resource<span class="token punctuation">.</span><span class="token function">setUsername</span><span class="token punctuation">(</span><span class="token string">"kie"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> resource<span class="token punctuation">.</span><span class="token function">setPassword</span><span class="token punctuation">(</span><span class="token string">"kie"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> resource<span class="token punctuation">.</span><span class="token function">setBasicAuthentication</span><span class="token punctuation">(</span><span class="token string">"enabled"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//将资源转换为输入流,通过此输入流可以读取jar包数据</span> <span class="token class-name">InputStream</span> inputStream <span class="token operator">=</span> resource<span class="token punctuation">.</span><span class="token function">getInputStream</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//创建仓库对象,仓库对象中保存Drools的规则信息</span> <span class="token class-name">KieRepository</span> repository <span class="token operator">=</span> kieServices<span class="token punctuation">.</span><span class="token function">getRepository</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//通过输入流读取maven仓库中的jar包数据,包装成KieModule模块添加到仓库中</span> <span class="token class-name">KieModule</span> kieModule <span class="token operator">=</span> repository<span class="token punctuation">.</span> <span class="token function">addKieModule</span><span class="token punctuation">(</span>kieServices<span class="token punctuation">.</span><span class="token function">getResources</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">newInputStreamResource</span><span class="token punctuation">(</span>inputStream<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//基于KieModule模块创建容器对象,从容器中可以获取session会话</span> <span class="token class-name">KieContainer</span> kieContainer <span class="token operator">=</span> kieServices<span class="token punctuation">.</span><span class="token function">newKieContainer</span><span class="token punctuation">(</span>kieModule<span class="token punctuation">.</span><span class="token function">getReleaseId</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">KieSession</span> session <span class="token operator">=</span> kieContainer<span class="token punctuation">.</span><span class="token function">newKieSession</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">Person</span> person <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Person</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> person<span class="token punctuation">.</span><span class="token function">setAge</span><span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">;</span> session<span class="token punctuation">.</span><span class="token function">insert</span><span class="token punctuation">(</span>person<span class="token punctuation">)</span><span class="token punctuation">;</span> session<span class="token punctuation">.</span><span class="token function">fireAllRules</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> session<span class="token punctuation">.</span><span class="token function">dispose</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>执行单元测试可以发现控制台已经输出了相关内容。通过WorkBench修改规则输出内容并发布,再次执行单元测试可以发现控制台输出的内容也发生了变化。</p><p><strong>通过上面的案例可以发现,我们在IEDA中开发的项目中并没有编写规则文件,规则文件是我们通过WorkBench开发并安装部署到maven仓库中,我们自己开发的项目只需要远程加载maven仓库中的jar包就可以完成规则的调用。这种开发方式的好处是我们的应用可以和业务规则完全分离,同时通过WorkBench修改规则后我们的应用不需要任何修改就可以加载到最新的规则从而实现规则的动态变更。</strong></p><h2 id="9-Drools实战"><a href="#9-Drools实战" class="headerlink" title="9. Drools实战"></a>9. Drools实战</h2><h3 id="9-1-个人所得税计算器"><a href="#9-1-个人所得税计算器" class="headerlink" title="9.1 个人所得税计算器"></a>9.1 个人所得税计算器</h3><p>本小节我们需要通过Drools规则引擎来根据规则计算个人所得税,最终页面效果如下:</p><p><img src="/media/pictures/Drools.assets/image-20200214132448956.png" alt="image-20200214132448956"></p><h4 id="9-1-1-名词解释"><a href="#9-1-1-名词解释" class="headerlink" title="9.1.1 名词解释"></a>9.1.1 名词解释</h4><p>税前月收入:即税前工资,指交纳个人所得税之前的总工资</p><p>应纳税所得额:指按照税法规定确定纳税人在一定期间所获得的所有应税收入减除在该纳税期间依法允许减除的各种支出后的余额</p><p>税率:是对征税对象的征收比例或征收额度</p><p>速算扣除数:指为解决超额累进税率分级计算税额的复杂技术问题,而预先计算出的一个数据,可以简化计算过程</p><p>扣税额:是指实际缴纳的税额</p><p>税后工资:是指扣完税后实际到手的工资收入</p><h4 id="9-1-2-计算规则"><a href="#9-1-2-计算规则" class="headerlink" title="9.1.2 计算规则"></a>9.1.2 计算规则</h4><p>要实现个人所得税计算器,需要了解如下计算规则:(2011)</p><table><thead><tr><th align="left">规则编号</th><th align="left">名称</th><th align="left">描述</th></tr></thead><tbody><tr><td align="left">1</td><td align="left">计算应纳税所得额</td><td align="left">应纳税所得额为税前工资减去3500</td></tr><tr><td align="left">2</td><td align="left">设置税率,应纳税所得额<=1500</td><td align="left">税率为0.03,速算扣除数为0</td></tr><tr><td align="left">3</td><td align="left">设置税率,应纳税所得额在1500至4500之间</td><td align="left">税率为0.1,速算扣除数为105</td></tr><tr><td align="left">4</td><td align="left">设置税率,应纳税所得额在4500志9000之间</td><td align="left">税率为0.2,速算扣除数为555</td></tr><tr><td align="left">5</td><td align="left">设置税率,应纳税所得额在9000志35000之间</td><td align="left">税率为0.25,速算扣除数为1005</td></tr><tr><td align="left">6</td><td align="left">设置税率,应纳税所得额在35000至55000之间</td><td align="left">税率为0.3,速算扣除数为2755</td></tr><tr><td align="left">7</td><td align="left">设置税率,应纳税所得额在55000至80000之间</td><td align="left">税率为0.35,速算扣除数为5505</td></tr><tr><td align="left">8</td><td align="left">设置税率,应纳税所得额在80000以上</td><td align="left">税率为0.45,速算扣除数为13505</td></tr><tr><td align="left">9</td><td align="left">计算税后工资</td><td align="left">扣税额=应纳税所得额*税率-速算扣除数 税后工资=税前工资-扣税额</td></tr></tbody></table><p>税前工资:10000</p><p>应缴纳所得税:10000-3500 = 6500</p><p>税率:0.2</p><p>速算扣除数:555</p><p>扣税额:6500 * 0.2 - 555 = 745</p><p>税后工资:10000 - 745 = 9255</p><h4 id="9-1-3-实现步骤"><a href="#9-1-3-实现步骤" class="headerlink" title="9.1.3 实现步骤"></a>9.1.3 实现步骤</h4><p>本实战案例我们基于Spring Boot整合Drools的方式来实现。</p><p>第一步:创建maven工程calculation并配置pom.xml文件</p><pre class="line-numbers language-xml" data-language="xml"><code class="language-xml"><span class="token prolog"><?xml version="1.0" encoding="UTF-8"?></span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>project</span> <span class="token attr-name">xmlns</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>http://maven.apache.org/POM/4.0.0<span class="token punctuation">"</span></span> <span class="token attr-name"><span class="token namespace">xmlns:</span>xsi</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>http://www.w3.org/2001/XMLSchema-instance<span class="token punctuation">"</span></span> <span class="token attr-name"><span class="token namespace">xsi:</span>schemaLocation</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>modelVersion</span><span class="token punctuation">></span></span>4.0.0<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>modelVersion</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>parent</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-boot-starters<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>2.0.6.RELEASE<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>parent</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>cn.itcast<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>calculation<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>1.0-SNAPSHOT<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependencies</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-boot-starter-web<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-boot-starter-aop<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-boot-starter-test<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>commons-lang<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>commons-lang<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>2.6<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token comment"><!--drools规则引擎--></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.drools<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>drools-core<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>7.6.0.Final<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.drools<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>drools-compiler<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>7.6.0.Final<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.drools<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>drools-templates<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>7.6.0.Final<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.kie<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>kie-api<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>7.6.0.Final<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.kie<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>kie-spring<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>exclusions</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>exclusion</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-tx<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>exclusion</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>exclusion</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-beans<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>exclusion</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>exclusion</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-core<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>exclusion</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>exclusion</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-context<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>exclusion</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>exclusions</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>7.6.0.Final<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependencies</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>build</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>finalName</span><span class="token punctuation">></span></span>${project.artifactId}<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>finalName</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>resources</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>resource</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>directory</span><span class="token punctuation">></span></span>src/main/java<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>directory</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>includes</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>include</span><span class="token punctuation">></span></span>**/*.xml<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>include</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>includes</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>filtering</span><span class="token punctuation">></span></span>false<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>filtering</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>resource</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>resource</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>directory</span><span class="token punctuation">></span></span>src/main/resources<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>directory</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>includes</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>include</span><span class="token punctuation">></span></span>**/*.*<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>include</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>includes</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>filtering</span><span class="token punctuation">></span></span>false<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>filtering</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>resource</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>resources</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>plugins</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>plugin</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.apache.maven.plugins<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>maven-compiler-plugin<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>2.3.2<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>configuration</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>source</span><span class="token punctuation">></span></span>1.8<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>source</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>target</span><span class="token punctuation">></span></span>1.8<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>target</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>configuration</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>plugin</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>plugins</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>build</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>project</span><span class="token punctuation">></span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>第二步:创建/resources/application.yml文件</p><pre class="line-numbers language-yml" data-language="yml"><code class="language-yml">server: port: 8080spring: application: name: calculation<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>第三步:编写配置类DroolsConfig</p><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">package</span> <span class="token namespace">com<span class="token punctuation">.</span>itheima<span class="token punctuation">.</span>drools<span class="token punctuation">.</span>config</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>kie<span class="token punctuation">.</span>api<span class="token punctuation">.</span></span><span class="token class-name">KieBase</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>kie<span class="token punctuation">.</span>api<span class="token punctuation">.</span></span><span class="token class-name">KieServices</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>kie<span class="token punctuation">.</span>api<span class="token punctuation">.</span>builder<span class="token punctuation">.</span></span><span class="token class-name">KieBuilder</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>kie<span class="token punctuation">.</span>api<span class="token punctuation">.</span>builder<span class="token punctuation">.</span></span><span class="token class-name">KieFileSystem</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>kie<span class="token punctuation">.</span>api<span class="token punctuation">.</span>builder<span class="token punctuation">.</span></span><span class="token class-name">KieRepository</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>kie<span class="token punctuation">.</span>api<span class="token punctuation">.</span>runtime<span class="token punctuation">.</span></span><span class="token class-name">KieContainer</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>kie<span class="token punctuation">.</span>api<span class="token punctuation">.</span>runtime<span class="token punctuation">.</span></span><span class="token class-name">KieSession</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>kie<span class="token punctuation">.</span>internal<span class="token punctuation">.</span>io<span class="token punctuation">.</span></span><span class="token class-name">ResourceFactory</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>kie<span class="token punctuation">.</span>spring<span class="token punctuation">.</span></span><span class="token class-name">KModuleBeanFactoryPostProcessor</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>boot<span class="token punctuation">.</span>autoconfigure<span class="token punctuation">.</span>condition<span class="token punctuation">.</span></span><span class="token class-name">ConditionalOnMissingBean</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>context<span class="token punctuation">.</span>annotation<span class="token punctuation">.</span></span><span class="token class-name">Bean</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>context<span class="token punctuation">.</span>annotation<span class="token punctuation">.</span></span><span class="token class-name">Configuration</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>core<span class="token punctuation">.</span>io<span class="token punctuation">.</span>support<span class="token punctuation">.</span></span><span class="token class-name">PathMatchingResourcePatternResolver</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>core<span class="token punctuation">.</span>io<span class="token punctuation">.</span>support<span class="token punctuation">.</span></span><span class="token class-name">ResourcePatternResolver</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>core<span class="token punctuation">.</span>io<span class="token punctuation">.</span></span><span class="token class-name">Resource</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">java<span class="token punctuation">.</span>io<span class="token punctuation">.</span></span><span class="token class-name">IOException</span><span class="token punctuation">;</span><span class="token comment">/** * 规则引擎配置类 */</span><span class="token annotation punctuation">@Configuration</span><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">DroolsConfig</span> <span class="token punctuation">{</span> <span class="token comment">//指定规则文件存放的目录</span> <span class="token keyword">private</span> <span class="token keyword">static</span> <span class="token keyword">final</span> <span class="token class-name">String</span> RULES_PATH <span class="token operator">=</span> <span class="token string">"rules/"</span><span class="token punctuation">;</span> <span class="token keyword">private</span> <span class="token keyword">final</span> <span class="token class-name">KieServices</span> kieServices <span class="token operator">=</span> <span class="token class-name">KieServices<span class="token punctuation">.</span>Factory</span><span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token annotation punctuation">@Bean</span> <span class="token annotation punctuation">@ConditionalOnMissingBean</span> <span class="token keyword">public</span> <span class="token class-name">KieFileSystem</span> <span class="token function">kieFileSystem</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">IOException</span> <span class="token punctuation">{</span> <span class="token class-name">System</span><span class="token punctuation">.</span><span class="token function">setProperty</span><span class="token punctuation">(</span><span class="token string">"drools.dateformat"</span><span class="token punctuation">,</span><span class="token string">"yyyy-MM-dd"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">KieFileSystem</span> kieFileSystem <span class="token operator">=</span> kieServices<span class="token punctuation">.</span><span class="token function">newKieFileSystem</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">ResourcePatternResolver</span> resourcePatternResolver <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">PathMatchingResourcePatternResolver</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">Resource</span><span class="token punctuation">[</span><span class="token punctuation">]</span> files <span class="token operator">=</span> resourcePatternResolver<span class="token punctuation">.</span><span class="token function">getResources</span><span class="token punctuation">(</span><span class="token string">"classpath*:"</span> <span class="token operator">+</span> RULES_PATH <span class="token operator">+</span> <span class="token string">"*.*"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">String</span> path <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token class-name">Resource</span> file <span class="token operator">:</span> files<span class="token punctuation">)</span> <span class="token punctuation">{</span> path <span class="token operator">=</span> RULES_PATH <span class="token operator">+</span> file<span class="token punctuation">.</span><span class="token function">getFilename</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> kieFileSystem<span class="token punctuation">.</span><span class="token function">write</span><span class="token punctuation">(</span><span class="token class-name">ResourceFactory</span><span class="token punctuation">.</span><span class="token function">newClassPathResource</span><span class="token punctuation">(</span>path<span class="token punctuation">,</span> <span class="token string">"UTF-8"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> kieFileSystem<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token annotation punctuation">@Bean</span> <span class="token annotation punctuation">@ConditionalOnMissingBean</span> <span class="token keyword">public</span> <span class="token class-name">KieContainer</span> <span class="token function">kieContainer</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">IOException</span> <span class="token punctuation">{</span> <span class="token class-name">KieRepository</span> kieRepository <span class="token operator">=</span> kieServices<span class="token punctuation">.</span><span class="token function">getRepository</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> kieRepository<span class="token punctuation">.</span><span class="token function">addKieModule</span><span class="token punctuation">(</span>kieRepository<span class="token operator">::</span><span class="token function">getDefaultReleaseId</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">KieBuilder</span> kieBuilder <span class="token operator">=</span> kieServices<span class="token punctuation">.</span><span class="token function">newKieBuilder</span><span class="token punctuation">(</span><span class="token function">kieFileSystem</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> kieBuilder<span class="token punctuation">.</span><span class="token function">buildAll</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> kieServices<span class="token punctuation">.</span><span class="token function">newKieContainer</span><span class="token punctuation">(</span>kieRepository<span class="token punctuation">.</span><span class="token function">getDefaultReleaseId</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token annotation punctuation">@Bean</span> <span class="token annotation punctuation">@ConditionalOnMissingBean</span> <span class="token keyword">public</span> <span class="token class-name">KieBase</span> <span class="token function">kieBase</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">IOException</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token function">kieContainer</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getKieBase</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token annotation punctuation">@Bean</span> <span class="token annotation punctuation">@ConditionalOnMissingBean</span> <span class="token keyword">public</span> <span class="token class-name">KModuleBeanFactoryPostProcessor</span> <span class="token function">kiePostProcessor</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">KModuleBeanFactoryPostProcessor</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>第四步:编写实体类Calculation</p><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">package</span> <span class="token namespace">com<span class="token punctuation">.</span>itheima<span class="token punctuation">.</span>drools<span class="token punctuation">.</span>entity</span><span class="token punctuation">;</span><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">Calculation</span> <span class="token punctuation">{</span> <span class="token keyword">private</span> <span class="token keyword">double</span> wage<span class="token punctuation">;</span><span class="token comment">//税前工资</span> <span class="token keyword">private</span> <span class="token keyword">double</span> wagemore<span class="token punctuation">;</span><span class="token comment">//应纳税所得额</span> <span class="token keyword">private</span> <span class="token keyword">double</span> cess<span class="token punctuation">;</span><span class="token comment">//税率</span> <span class="token keyword">private</span> <span class="token keyword">double</span> preminus<span class="token punctuation">;</span><span class="token comment">//速算扣除数</span> <span class="token keyword">private</span> <span class="token keyword">double</span> wageminus<span class="token punctuation">;</span><span class="token comment">//扣税额</span> <span class="token keyword">private</span> <span class="token keyword">double</span> actualwage<span class="token punctuation">;</span><span class="token comment">//税后工资</span> <span class="token keyword">public</span> <span class="token keyword">double</span> <span class="token function">getWage</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> wage<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setWage</span><span class="token punctuation">(</span><span class="token keyword">double</span> wage<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>wage <span class="token operator">=</span> wage<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">double</span> <span class="token function">getActualwage</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> actualwage<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setActualwage</span><span class="token punctuation">(</span><span class="token keyword">double</span> actualwage<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>actualwage <span class="token operator">=</span> actualwage<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">double</span> <span class="token function">getWagemore</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> wagemore<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setWagemore</span><span class="token punctuation">(</span><span class="token keyword">double</span> wagemore<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>wagemore <span class="token operator">=</span> wagemore<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">double</span> <span class="token function">getCess</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> cess<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setCess</span><span class="token punctuation">(</span><span class="token keyword">double</span> cess<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>cess <span class="token operator">=</span> cess<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">double</span> <span class="token function">getPreminus</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> preminus<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setPreminus</span><span class="token punctuation">(</span><span class="token keyword">double</span> preminus<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>preminus <span class="token operator">=</span> preminus<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">double</span> <span class="token function">getWageminus</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> wageminus<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setWageminus</span><span class="token punctuation">(</span><span class="token keyword">double</span> wageminus<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>wageminus <span class="token operator">=</span> wageminus<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token annotation punctuation">@Override</span> <span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token string">"Calculation{"</span> <span class="token operator">+</span> <span class="token string">"wage="</span> <span class="token operator">+</span> wage <span class="token operator">+</span> <span class="token string">", actualwage="</span> <span class="token operator">+</span> actualwage <span class="token operator">+</span> <span class="token string">", wagemore="</span> <span class="token operator">+</span> wagemore <span class="token operator">+</span> <span class="token string">", cess="</span> <span class="token operator">+</span> cess <span class="token operator">+</span> <span class="token string">", preminus="</span> <span class="token operator">+</span> preminus <span class="token operator">+</span> <span class="token string">", wageminus="</span> <span class="token operator">+</span> wageminus <span class="token operator">+</span> <span class="token char">'}'</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>第五步:在resources/rules下创建规则文件calculation.drl文件</p><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">package</span> <span class="token namespace">calculation</span><span class="token keyword">import</span> <span class="token namespace">com<span class="token punctuation">.</span>itheima<span class="token punctuation">.</span>drools<span class="token punctuation">.</span>entity<span class="token punctuation">.</span></span><span class="token class-name">Calculation</span>rule <span class="token string">"个人所得税:计算应纳税所得额"</span> enabled <span class="token boolean">true</span> salience <span class="token number">3</span> no<span class="token operator">-</span>loop <span class="token boolean">true</span> date<span class="token operator">-</span>effective <span class="token string">"2011-09-01"</span> <span class="token comment">//生效日期</span> when $cal <span class="token operator">:</span> <span class="token class-name">Calculation</span><span class="token punctuation">(</span>wage<span class="token operator">></span><span class="token number">0</span><span class="token punctuation">)</span> then $cal<span class="token punctuation">.</span><span class="token function">setWagemore</span><span class="token punctuation">(</span>$cal<span class="token punctuation">.</span><span class="token function">getWage</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-</span><span class="token number">3500</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">update</span><span class="token punctuation">(</span>$cal<span class="token punctuation">)</span><span class="token punctuation">;</span>endrule <span class="token string">"个人所得税:设置税率-->>应纳税所得额<=1500"</span> salience <span class="token number">2</span> no<span class="token operator">-</span>loop <span class="token boolean">true</span> activation<span class="token operator">-</span>group <span class="token string">"SETCess_Group"</span> when $cal <span class="token operator">:</span> <span class="token class-name">Calculation</span><span class="token punctuation">(</span>wagemore <span class="token operator"><=</span> <span class="token number">1500</span><span class="token punctuation">)</span> then $cal<span class="token punctuation">.</span><span class="token function">setCess</span><span class="token punctuation">(</span><span class="token number">0.03</span><span class="token punctuation">)</span><span class="token punctuation">;</span> $cal<span class="token punctuation">.</span><span class="token function">setPreminus</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">update</span><span class="token punctuation">(</span>$cal<span class="token punctuation">)</span><span class="token punctuation">;</span>endrule <span class="token string">"个人所得税:设置税率-->>应纳税所得额在1500至4500之间"</span> salience <span class="token number">2</span> no<span class="token operator">-</span>loop <span class="token boolean">true</span> activation<span class="token operator">-</span>group <span class="token string">"SETCess_Group"</span> when $cal <span class="token operator">:</span> <span class="token class-name">Calculation</span><span class="token punctuation">(</span>wagemore <span class="token operator">></span> <span class="token number">1500</span> <span class="token operator">&&</span> wagemore <span class="token operator"><=</span> <span class="token number">4500</span><span class="token punctuation">)</span> then $cal<span class="token punctuation">.</span><span class="token function">setCess</span><span class="token punctuation">(</span><span class="token number">0.1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> $cal<span class="token punctuation">.</span><span class="token function">setPreminus</span><span class="token punctuation">(</span><span class="token number">105</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">update</span><span class="token punctuation">(</span>$cal<span class="token punctuation">)</span><span class="token punctuation">;</span>endrule <span class="token string">"个人所得税:设置税率-->>应纳税所得额在4500志9000之间"</span> salience <span class="token number">2</span> no<span class="token operator">-</span>loop <span class="token boolean">true</span> activation<span class="token operator">-</span>group <span class="token string">"SETCess_Group"</span> when $cal <span class="token operator">:</span> <span class="token class-name">Calculation</span><span class="token punctuation">(</span>wagemore <span class="token operator">></span> <span class="token number">4500</span> <span class="token operator">&&</span> wagemore <span class="token operator"><=</span> <span class="token number">9000</span><span class="token punctuation">)</span> then $cal<span class="token punctuation">.</span><span class="token function">setCess</span><span class="token punctuation">(</span><span class="token number">0.2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> $cal<span class="token punctuation">.</span><span class="token function">setPreminus</span><span class="token punctuation">(</span><span class="token number">555</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">update</span><span class="token punctuation">(</span>$cal<span class="token punctuation">)</span><span class="token punctuation">;</span>endrule <span class="token string">"个人所得税:设置税率-->>应纳税所得额在9000志35000之间"</span> salience <span class="token number">2</span> no<span class="token operator">-</span>loop <span class="token boolean">true</span> activation<span class="token operator">-</span>group <span class="token string">"SETCess_Group"</span> when $cal <span class="token operator">:</span> <span class="token class-name">Calculation</span><span class="token punctuation">(</span>wagemore <span class="token operator">></span> <span class="token number">9000</span> <span class="token operator">&&</span> wagemore <span class="token operator"><=</span> <span class="token number">35000</span><span class="token punctuation">)</span> then $cal<span class="token punctuation">.</span><span class="token function">setCess</span><span class="token punctuation">(</span><span class="token number">0.25</span><span class="token punctuation">)</span><span class="token punctuation">;</span> $cal<span class="token punctuation">.</span><span class="token function">setPreminus</span><span class="token punctuation">(</span><span class="token number">1005</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">update</span><span class="token punctuation">(</span>$cal<span class="token punctuation">)</span><span class="token punctuation">;</span>endrule <span class="token string">"个人所得税:设置税率-->>应纳税所得额在35000至55000之间"</span> salience <span class="token number">2</span> no<span class="token operator">-</span>loop <span class="token boolean">true</span> activation<span class="token operator">-</span>group <span class="token string">"SETCess_Group"</span> when $cal <span class="token operator">:</span> <span class="token class-name">Calculation</span><span class="token punctuation">(</span>wagemore <span class="token operator">></span> <span class="token number">35000</span> <span class="token operator">&&</span> wagemore <span class="token operator"><=</span> <span class="token number">55000</span><span class="token punctuation">)</span> then $cal<span class="token punctuation">.</span><span class="token function">setCess</span><span class="token punctuation">(</span><span class="token number">0.3</span><span class="token punctuation">)</span><span class="token punctuation">;</span> $cal<span class="token punctuation">.</span><span class="token function">setPreminus</span><span class="token punctuation">(</span><span class="token number">2755</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">update</span><span class="token punctuation">(</span>$cal<span class="token punctuation">)</span><span class="token punctuation">;</span>endrule <span class="token string">"个人所得税:设置税率-->>应纳税所得额在55000至80000之间"</span> salience <span class="token number">2</span> no<span class="token operator">-</span>loop <span class="token boolean">true</span> activation<span class="token operator">-</span>group <span class="token string">"SETCess_Group"</span> when $cal <span class="token operator">:</span> <span class="token class-name">Calculation</span><span class="token punctuation">(</span>wagemore <span class="token operator">></span> <span class="token number">55000</span> <span class="token operator">&&</span> wagemore <span class="token operator"><=</span> <span class="token number">80000</span><span class="token punctuation">)</span> then $cal<span class="token punctuation">.</span><span class="token function">setCess</span><span class="token punctuation">(</span><span class="token number">0.35</span><span class="token punctuation">)</span><span class="token punctuation">;</span> $cal<span class="token punctuation">.</span><span class="token function">setPreminus</span><span class="token punctuation">(</span><span class="token number">5505</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">update</span><span class="token punctuation">(</span>$cal<span class="token punctuation">)</span><span class="token punctuation">;</span>endrule <span class="token string">"个人所得税:设置税率-->>应纳税所得额在80000以上"</span> salience <span class="token number">2</span> no<span class="token operator">-</span>loop <span class="token boolean">true</span> activation<span class="token operator">-</span>group <span class="token string">"SETCess_Group"</span> when $cal <span class="token operator">:</span> <span class="token class-name">Calculation</span><span class="token punctuation">(</span>wagemore <span class="token operator">></span> <span class="token number">80000</span><span class="token punctuation">)</span> then $cal<span class="token punctuation">.</span><span class="token function">setCess</span><span class="token punctuation">(</span><span class="token number">0.45</span><span class="token punctuation">)</span><span class="token punctuation">;</span> $cal<span class="token punctuation">.</span><span class="token function">setPreminus</span><span class="token punctuation">(</span><span class="token number">13505</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">update</span><span class="token punctuation">(</span>$cal<span class="token punctuation">)</span><span class="token punctuation">;</span>endrule <span class="token string">"个人所得税:计算税后工资"</span> salience <span class="token number">1</span> when $cal <span class="token operator">:</span> <span class="token class-name">Calculation</span><span class="token punctuation">(</span>wage <span class="token operator">></span> <span class="token number">0</span> <span class="token operator">&&</span> wagemore <span class="token operator">></span> <span class="token number">0</span> <span class="token operator">&&</span> wagemore <span class="token operator">></span> <span class="token number">0</span> <span class="token operator">&&</span> cess <span class="token operator">></span> <span class="token number">0</span><span class="token punctuation">)</span> then $cal<span class="token punctuation">.</span><span class="token function">setWageminus</span><span class="token punctuation">(</span>$cal<span class="token punctuation">.</span><span class="token function">getWagemore</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">*</span>$cal<span class="token punctuation">.</span><span class="token function">getCess</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-</span>$cal<span class="token punctuation">.</span><span class="token function">getPreminus</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> $cal<span class="token punctuation">.</span><span class="token function">setActualwage</span><span class="token punctuation">(</span>$cal<span class="token punctuation">.</span><span class="token function">getWage</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-</span>$cal<span class="token punctuation">.</span><span class="token function">getWageminus</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"-----税前工资:"</span><span class="token operator">+</span>$cal<span class="token punctuation">.</span><span class="token function">getWage</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"-----应纳税所得额:"</span><span class="token operator">+</span>$cal<span class="token punctuation">.</span><span class="token function">getWagemore</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"-----税率:"</span> <span class="token operator">+</span> $cal<span class="token punctuation">.</span><span class="token function">getCess</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"-----速算扣除数:"</span> <span class="token operator">+</span> $cal<span class="token punctuation">.</span><span class="token function">getPreminus</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"-----扣税额:"</span> <span class="token operator">+</span> $cal<span class="token punctuation">.</span><span class="token function">getWageminus</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"-----税后工资:"</span> <span class="token operator">+</span> $cal<span class="token punctuation">.</span><span class="token function">getActualwage</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>end<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>第六步:创建RuleService</p><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">package</span> <span class="token namespace">com<span class="token punctuation">.</span>itheima<span class="token punctuation">.</span>drools<span class="token punctuation">.</span>service</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">com<span class="token punctuation">.</span>itheima<span class="token punctuation">.</span>drools<span class="token punctuation">.</span>entity<span class="token punctuation">.</span></span><span class="token class-name">Calculation</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>kie<span class="token punctuation">.</span>api<span class="token punctuation">.</span></span><span class="token class-name">KieBase</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>kie<span class="token punctuation">.</span>api<span class="token punctuation">.</span>runtime<span class="token punctuation">.</span></span><span class="token class-name">KieSession</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>beans<span class="token punctuation">.</span>factory<span class="token punctuation">.</span>annotation<span class="token punctuation">.</span></span><span class="token class-name">Autowired</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>stereotype<span class="token punctuation">.</span></span><span class="token class-name">Service</span><span class="token punctuation">;</span><span class="token comment">/** * 调用规则引擎,执行规则 */</span><span class="token annotation punctuation">@Service</span><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">RuleService</span> <span class="token punctuation">{</span> <span class="token annotation punctuation">@Autowired</span> <span class="token keyword">private</span> <span class="token class-name">KieBase</span> kieBase<span class="token punctuation">;</span> <span class="token comment">//个人所得税计算</span> <span class="token keyword">public</span> <span class="token class-name">Calculation</span> <span class="token function">calculate</span><span class="token punctuation">(</span><span class="token class-name">Calculation</span> calculation<span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token class-name">KieSession</span> kieSession <span class="token operator">=</span> kieBase<span class="token punctuation">.</span><span class="token function">newKieSession</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> kieSession<span class="token punctuation">.</span><span class="token function">insert</span><span class="token punctuation">(</span>calculation<span class="token punctuation">)</span><span class="token punctuation">;</span> kieSession<span class="token punctuation">.</span><span class="token function">fireAllRules</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> kieSession<span class="token punctuation">.</span><span class="token function">dispose</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> calculation<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>第七步:创建RuleController</p><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">package</span> <span class="token namespace">com<span class="token punctuation">.</span>itheima<span class="token punctuation">.</span>drools<span class="token punctuation">.</span>controller</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">com<span class="token punctuation">.</span>itheima<span class="token punctuation">.</span>drools<span class="token punctuation">.</span>entity<span class="token punctuation">.</span></span><span class="token class-name">Calculation</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">com<span class="token punctuation">.</span>itheima<span class="token punctuation">.</span>drools<span class="token punctuation">.</span>service<span class="token punctuation">.</span></span><span class="token class-name">RuleService</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>beans<span class="token punctuation">.</span>factory<span class="token punctuation">.</span>annotation<span class="token punctuation">.</span></span><span class="token class-name">Autowired</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>web<span class="token punctuation">.</span>bind<span class="token punctuation">.</span>annotation<span class="token punctuation">.</span></span><span class="token class-name">RequestMapping</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>web<span class="token punctuation">.</span>bind<span class="token punctuation">.</span>annotation<span class="token punctuation">.</span></span><span class="token class-name">RestController</span><span class="token punctuation">;</span><span class="token annotation punctuation">@RestController</span><span class="token annotation punctuation">@RequestMapping</span><span class="token punctuation">(</span><span class="token string">"/rule"</span><span class="token punctuation">)</span><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">RuleController</span> <span class="token punctuation">{</span> <span class="token annotation punctuation">@Autowired</span> <span class="token keyword">private</span> <span class="token class-name">RuleService</span> ruleService<span class="token punctuation">;</span> <span class="token annotation punctuation">@RequestMapping</span><span class="token punctuation">(</span><span class="token string">"/calculate"</span><span class="token punctuation">)</span> <span class="token keyword">public</span> <span class="token class-name">Calculation</span> <span class="token function">calculate</span><span class="token punctuation">(</span><span class="token keyword">double</span> wage<span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token class-name">Calculation</span> calculation <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Calculation</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> calculation<span class="token punctuation">.</span><span class="token function">setWage</span><span class="token punctuation">(</span>wage<span class="token punctuation">)</span><span class="token punctuation">;</span> calculation <span class="token operator">=</span> ruleService<span class="token punctuation">.</span><span class="token function">calculate</span><span class="token punctuation">(</span>calculation<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>calculation<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> calculation<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>第八步:创建启动类DroolsApplication</p><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">package</span> <span class="token namespace">com<span class="token punctuation">.</span>itheima<span class="token punctuation">.</span>drools</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>boot<span class="token punctuation">.</span></span><span class="token class-name">SpringApplication</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>boot<span class="token punctuation">.</span>autoconfigure<span class="token punctuation">.</span></span><span class="token class-name">SpringBootApplication</span><span class="token punctuation">;</span><span class="token annotation punctuation">@SpringBootApplication</span><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">DroolsApplication</span> <span class="token punctuation">{</span> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token class-name">String</span><span class="token punctuation">[</span><span class="token punctuation">]</span> args<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token class-name">SpringApplication</span><span class="token punctuation">.</span><span class="token function">run</span><span class="token punctuation">(</span><span class="token class-name">DroolsApplication</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>第九步:导入静态资源文件到resources/static目录下</p><h3 id="9-2-信用卡申请"><a href="#9-2-信用卡申请" class="headerlink" title="9.2 信用卡申请"></a>9.2 信用卡申请</h3><p>本小节我们需要通过Drools规则引擎来根据规则进行申请人的合法性检查,检查通过后再根据规则确定信用卡额度,最终页面效果如下:</p><p><img src="/media/pictures/Drools.assets/image-20200214202525859.png" alt="image-20200214202525859"></p><h4 id="9-2-1-计算规则"><a href="#9-2-1-计算规则" class="headerlink" title="9.2.1 计算规则"></a>9.2.1 计算规则</h4><p>合法性检查规则如下:</p><table><thead><tr><th align="left">规则编号</th><th align="left">名称</th><th align="left">描述</th></tr></thead><tbody><tr><td align="left">1</td><td align="left">检查学历与薪水1</td><td align="left">如果申请人既没房也没车,同时学历为大专以下,并且月薪少于5000,那么不通过</td></tr><tr><td align="left">2</td><td align="left">检查学历与薪水2</td><td align="left">如果申请人既没房也没车,同时学历为大专或本科,并且月薪少于3000,那么不通过</td></tr><tr><td align="left">3</td><td align="left">检查学历与薪水3</td><td align="left">如果申请人既没房也没车,同时学历为本科以上,并且月薪少于2000,同时之前没有信用卡的,那么不通过</td></tr><tr><td align="left">4</td><td align="left">检查申请人已有的信用卡数量</td><td align="left">如果申请人现有的信用卡数量大于10,那么不通过</td></tr></tbody></table><p>信用卡额度确定规则:</p><table><thead><tr><th align="left">规则编号</th><th align="left">名称</th><th align="left">描述</th></tr></thead><tbody><tr><td align="left">1</td><td align="left">规则1</td><td align="left">如果申请人有房有车,或者月收入在20000以上,那么发放的信用卡额度为15000</td></tr><tr><td align="left">2</td><td align="left">规则2</td><td align="left">如果申请人没房没车,但月收入在10000~20000之间,那么发放的信用卡额度为6000</td></tr><tr><td align="left">3</td><td align="left">规则3</td><td align="left">如果申请人没房没车,月收入在10000以下,那么发放的信用卡额度为3000</td></tr><tr><td align="left">4</td><td align="left">规则4</td><td align="left">如果申请人有房没车或者没房但有车,月收入在10000以下,那么发放的信用卡额度为5000</td></tr><tr><td align="left">5</td><td align="left">规则5</td><td align="left">如果申请人有房没车或者是没房但有车,月收入在10000~20000之间,那么发放的信用卡额度为8000</td></tr></tbody></table><h4 id="9-2-2-实现步骤"><a href="#9-2-2-实现步骤" class="headerlink" title="9.2.2 实现步骤"></a>9.2.2 实现步骤</h4><p>第一步:创建maven工程creditCardApply并配置pom.xml文件</p><pre class="line-numbers language-xml" data-language="xml"><code class="language-xml"><span class="token prolog"><?xml version="1.0" encoding="UTF-8"?></span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>project</span> <span class="token attr-name">xmlns</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>http://maven.apache.org/POM/4.0.0<span class="token punctuation">"</span></span> <span class="token attr-name"><span class="token namespace">xmlns:</span>xsi</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>http://www.w3.org/2001/XMLSchema-instance<span class="token punctuation">"</span></span> <span class="token attr-name"><span class="token namespace">xsi:</span>schemaLocation</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>modelVersion</span><span class="token punctuation">></span></span>4.0.0<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>modelVersion</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>parent</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-boot-starters<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>2.0.6.RELEASE<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>parent</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>com.itheima<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>creditCardApply<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>1.0-SNAPSHOT<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependencies</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-boot-starter-web<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-boot-starter-aop<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-boot-starter-test<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>commons-lang<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>commons-lang<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>2.6<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token comment"><!--drools规则引擎--></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.drools<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>drools-core<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>7.6.0.Final<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.drools<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>drools-compiler<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>7.6.0.Final<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.drools<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>drools-templates<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>7.6.0.Final<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.kie<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>kie-api<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>7.6.0.Final<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.kie<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>kie-spring<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>exclusions</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>exclusion</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-tx<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>exclusion</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>exclusion</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-beans<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>exclusion</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>exclusion</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-core<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>exclusion</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>exclusion</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-context<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>exclusion</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>exclusions</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>7.6.0.Final<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependencies</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>build</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>finalName</span><span class="token punctuation">></span></span>${project.artifactId}<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>finalName</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>resources</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>resource</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>directory</span><span class="token punctuation">></span></span>src/main/java<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>directory</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>includes</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>include</span><span class="token punctuation">></span></span>**/*.xml<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>include</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>includes</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>filtering</span><span class="token punctuation">></span></span>false<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>filtering</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>resource</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>resource</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>directory</span><span class="token punctuation">></span></span>src/main/resources<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>directory</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>includes</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>include</span><span class="token punctuation">></span></span>**/*.*<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>include</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>includes</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>filtering</span><span class="token punctuation">></span></span>false<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>filtering</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>resource</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>resources</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>plugins</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>plugin</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.apache.maven.plugins<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>maven-compiler-plugin<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>2.3.2<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>configuration</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>source</span><span class="token punctuation">></span></span>1.8<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>source</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>target</span><span class="token punctuation">></span></span>1.8<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>target</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>configuration</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>plugin</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>plugins</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>build</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>project</span><span class="token punctuation">></span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>第二步:创建/resources/application.yml文件</p><pre class="line-numbers language-yml" data-language="yml"><code class="language-yml">server: port: 8080spring: application: name: creditCardApply<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>第三步:编写配置类DroolsConfig</p><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">package</span> <span class="token namespace">com<span class="token punctuation">.</span>itheima<span class="token punctuation">.</span>drools<span class="token punctuation">.</span>config</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>kie<span class="token punctuation">.</span>api<span class="token punctuation">.</span></span><span class="token class-name">KieBase</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>kie<span class="token punctuation">.</span>api<span class="token punctuation">.</span></span><span class="token class-name">KieServices</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>kie<span class="token punctuation">.</span>api<span class="token punctuation">.</span>builder<span class="token punctuation">.</span></span><span class="token class-name">KieBuilder</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>kie<span class="token punctuation">.</span>api<span class="token punctuation">.</span>builder<span class="token punctuation">.</span></span><span class="token class-name">KieFileSystem</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>kie<span class="token punctuation">.</span>api<span class="token punctuation">.</span>builder<span class="token punctuation">.</span></span><span class="token class-name">KieRepository</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>kie<span class="token punctuation">.</span>api<span class="token punctuation">.</span>runtime<span class="token punctuation">.</span></span><span class="token class-name">KieContainer</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>kie<span class="token punctuation">.</span>api<span class="token punctuation">.</span>runtime<span class="token punctuation">.</span></span><span class="token class-name">KieSession</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>kie<span class="token punctuation">.</span>internal<span class="token punctuation">.</span>io<span class="token punctuation">.</span></span><span class="token class-name">ResourceFactory</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>kie<span class="token punctuation">.</span>spring<span class="token punctuation">.</span></span><span class="token class-name">KModuleBeanFactoryPostProcessor</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>boot<span class="token punctuation">.</span>autoconfigure<span class="token punctuation">.</span>condition<span class="token punctuation">.</span></span><span class="token class-name">ConditionalOnMissingBean</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>context<span class="token punctuation">.</span>annotation<span class="token punctuation">.</span></span><span class="token class-name">Bean</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>context<span class="token punctuation">.</span>annotation<span class="token punctuation">.</span></span><span class="token class-name">Configuration</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>core<span class="token punctuation">.</span>io<span class="token punctuation">.</span>support<span class="token punctuation">.</span></span><span class="token class-name">PathMatchingResourcePatternResolver</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>core<span class="token punctuation">.</span>io<span class="token punctuation">.</span>support<span class="token punctuation">.</span></span><span class="token class-name">ResourcePatternResolver</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>core<span class="token punctuation">.</span>io<span class="token punctuation">.</span></span><span class="token class-name">Resource</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">java<span class="token punctuation">.</span>io<span class="token punctuation">.</span></span><span class="token class-name">IOException</span><span class="token punctuation">;</span><span class="token comment">/** * 规则引擎配置类 */</span><span class="token annotation punctuation">@Configuration</span><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">DroolsConfig</span> <span class="token punctuation">{</span> <span class="token comment">//指定规则文件存放的目录</span> <span class="token keyword">private</span> <span class="token keyword">static</span> <span class="token keyword">final</span> <span class="token class-name">String</span> RULES_PATH <span class="token operator">=</span> <span class="token string">"rules/"</span><span class="token punctuation">;</span> <span class="token keyword">private</span> <span class="token keyword">final</span> <span class="token class-name">KieServices</span> kieServices <span class="token operator">=</span> <span class="token class-name">KieServices<span class="token punctuation">.</span>Factory</span><span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token annotation punctuation">@Bean</span> <span class="token annotation punctuation">@ConditionalOnMissingBean</span> <span class="token keyword">public</span> <span class="token class-name">KieFileSystem</span> <span class="token function">kieFileSystem</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">IOException</span> <span class="token punctuation">{</span> <span class="token class-name">KieFileSystem</span> kieFileSystem <span class="token operator">=</span> kieServices<span class="token punctuation">.</span><span class="token function">newKieFileSystem</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">ResourcePatternResolver</span> resourcePatternResolver <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">PathMatchingResourcePatternResolver</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">Resource</span><span class="token punctuation">[</span><span class="token punctuation">]</span> files <span class="token operator">=</span> resourcePatternResolver<span class="token punctuation">.</span><span class="token function">getResources</span><span class="token punctuation">(</span><span class="token string">"classpath*:"</span> <span class="token operator">+</span> RULES_PATH <span class="token operator">+</span> <span class="token string">"*.*"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">String</span> path <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token class-name">Resource</span> file <span class="token operator">:</span> files<span class="token punctuation">)</span> <span class="token punctuation">{</span> path <span class="token operator">=</span> RULES_PATH <span class="token operator">+</span> file<span class="token punctuation">.</span><span class="token function">getFilename</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> kieFileSystem<span class="token punctuation">.</span><span class="token function">write</span><span class="token punctuation">(</span><span class="token class-name">ResourceFactory</span><span class="token punctuation">.</span><span class="token function">newClassPathResource</span><span class="token punctuation">(</span>path<span class="token punctuation">,</span> <span class="token string">"UTF-8"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> kieFileSystem<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token annotation punctuation">@Bean</span> <span class="token annotation punctuation">@ConditionalOnMissingBean</span> <span class="token keyword">public</span> <span class="token class-name">KieContainer</span> <span class="token function">kieContainer</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">IOException</span> <span class="token punctuation">{</span> <span class="token class-name">KieRepository</span> kieRepository <span class="token operator">=</span> kieServices<span class="token punctuation">.</span><span class="token function">getRepository</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> kieRepository<span class="token punctuation">.</span><span class="token function">addKieModule</span><span class="token punctuation">(</span>kieRepository<span class="token operator">::</span><span class="token function">getDefaultReleaseId</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">KieBuilder</span> kieBuilder <span class="token operator">=</span> kieServices<span class="token punctuation">.</span><span class="token function">newKieBuilder</span><span class="token punctuation">(</span><span class="token function">kieFileSystem</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> kieBuilder<span class="token punctuation">.</span><span class="token function">buildAll</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> kieServices<span class="token punctuation">.</span><span class="token function">newKieContainer</span><span class="token punctuation">(</span>kieRepository<span class="token punctuation">.</span><span class="token function">getDefaultReleaseId</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token annotation punctuation">@Bean</span> <span class="token annotation punctuation">@ConditionalOnMissingBean</span> <span class="token keyword">public</span> <span class="token class-name">KieBase</span> <span class="token function">kieBase</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">IOException</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token function">kieContainer</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getKieBase</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token annotation punctuation">@Bean</span> <span class="token annotation punctuation">@ConditionalOnMissingBean</span> <span class="token keyword">public</span> <span class="token class-name">KModuleBeanFactoryPostProcessor</span> <span class="token function">kiePostProcessor</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">KModuleBeanFactoryPostProcessor</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>第四步:编写实体类CreditCardApplyInfo</p><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">package</span> <span class="token namespace">com<span class="token punctuation">.</span>itheima<span class="token punctuation">.</span>drools<span class="token punctuation">.</span>entity</span><span class="token punctuation">;</span><span class="token comment">/** * 信用卡申请信息 */</span><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">CreditCardApplyInfo</span> <span class="token punctuation">{</span> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">final</span> <span class="token class-name">String</span> EDUCATION_1 <span class="token operator">=</span> <span class="token string">"专科以下"</span><span class="token punctuation">;</span> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">final</span> <span class="token class-name">String</span> EDUCATION_2 <span class="token operator">=</span> <span class="token string">"专科"</span><span class="token punctuation">;</span> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">final</span> <span class="token class-name">String</span> EDUCATION_3 <span class="token operator">=</span> <span class="token string">"本科"</span><span class="token punctuation">;</span> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">final</span> <span class="token class-name">String</span> EDUCATION_4 <span class="token operator">=</span> <span class="token string">"本科以上"</span><span class="token punctuation">;</span> <span class="token keyword">private</span> <span class="token class-name">String</span> name<span class="token punctuation">;</span> <span class="token keyword">private</span> <span class="token class-name">String</span> sex<span class="token punctuation">;</span> <span class="token keyword">private</span> <span class="token keyword">int</span> age<span class="token punctuation">;</span> <span class="token keyword">private</span> <span class="token class-name">String</span> education<span class="token punctuation">;</span> <span class="token keyword">private</span> <span class="token class-name">String</span> telephone<span class="token punctuation">;</span> <span class="token keyword">private</span> <span class="token keyword">double</span> monthlyIncome <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token comment">//月收入</span> <span class="token keyword">private</span> <span class="token class-name">String</span> address<span class="token punctuation">;</span> <span class="token keyword">private</span> <span class="token keyword">boolean</span> hasHouse <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span><span class="token comment">//是否有房</span> <span class="token keyword">private</span> <span class="token keyword">boolean</span> hasCar <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span><span class="token comment">//是否有车</span> <span class="token keyword">private</span> <span class="token keyword">int</span> hasCreditCardCount <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token comment">//现持有信用卡数量</span> <span class="token keyword">private</span> <span class="token keyword">boolean</span> checkResult <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span><span class="token comment">//审核是否通过</span> <span class="token keyword">private</span> <span class="token keyword">double</span> quota <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token comment">//额度</span> <span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> name<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setName</span><span class="token punctuation">(</span><span class="token class-name">String</span> name<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">getSex</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> sex<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setSex</span><span class="token punctuation">(</span><span class="token class-name">String</span> sex<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>sex <span class="token operator">=</span> sex<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">int</span> <span class="token function">getAge</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> age<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setAge</span><span class="token punctuation">(</span><span class="token keyword">int</span> age<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>age <span class="token operator">=</span> age<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">getEducation</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> education<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setEducation</span><span class="token punctuation">(</span><span class="token class-name">String</span> education<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>education <span class="token operator">=</span> education<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">getTelephone</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> telephone<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setTelephone</span><span class="token punctuation">(</span><span class="token class-name">String</span> telephone<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>telephone <span class="token operator">=</span> telephone<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">double</span> <span class="token function">getMonthlyIncome</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> monthlyIncome<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setMonthlyIncome</span><span class="token punctuation">(</span><span class="token keyword">double</span> monthlyIncome<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>monthlyIncome <span class="token operator">=</span> monthlyIncome<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">getAddress</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> address<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setAddress</span><span class="token punctuation">(</span><span class="token class-name">String</span> address<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>address <span class="token operator">=</span> address<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">boolean</span> <span class="token function">isHasHouse</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> hasHouse<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setHasHouse</span><span class="token punctuation">(</span><span class="token keyword">boolean</span> hasHouse<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>hasHouse <span class="token operator">=</span> hasHouse<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">boolean</span> <span class="token function">isHasCar</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> hasCar<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setHasCar</span><span class="token punctuation">(</span><span class="token keyword">boolean</span> hasCar<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>hasCar <span class="token operator">=</span> hasCar<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">int</span> <span class="token function">getHasCreditCardCount</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> hasCreditCardCount<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setHasCreditCardCount</span><span class="token punctuation">(</span><span class="token keyword">int</span> hasCreditCardCount<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>hasCreditCardCount <span class="token operator">=</span> hasCreditCardCount<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">boolean</span> <span class="token function">isCheckResult</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> checkResult<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setCheckResult</span><span class="token punctuation">(</span><span class="token keyword">boolean</span> checkResult<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>checkResult <span class="token operator">=</span> checkResult<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">double</span> <span class="token function">getQuota</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> quota<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setQuota</span><span class="token punctuation">(</span><span class="token keyword">double</span> quota<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>quota <span class="token operator">=</span> quota<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span><span class="token punctuation">(</span>checkResult<span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token string">"审核通过,信用卡额度为:"</span> <span class="token operator">+</span> quota<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token string">"审核不通过"</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>第五步:在resources/rules下创建规则文件creditCardApply.drl文件</p><pre class="line-numbers language-none"><code class="language-none">package com.itheima.creditCardApplyimport com.itheima.drools.entity.CreditCardApplyInfo//合法性检查rule "如果申请人既没房也没车,同时学历为大专以下,并且月薪少于5000,那么不通过" salience 10 no-loop true when $c:CreditCardApplyInfo(hasCar == false && hasHouse == false && education == CreditCardApplyInfo.EDUCATION_1 && monthlyIncome < 5000) then $c.setCheckResult(false); drools.halt();endrule "如果申请人既没房也没车,同时学历为大专或本科,并且月薪少于3000,那么不通过" salience 10 no-loop true when $c:CreditCardApplyInfo(hasCar == false && hasHouse == false && (education == CreditCardApplyInfo.EDUCATION_2 || education == CreditCardApplyInfo.EDUCATION_3) && monthlyIncome < 3000) then $c.setCheckResult(false); drools.halt();endrule "如果申请人既没房也没车,同时学历为本科以上,并且月薪少于2000,同时之前没有信用卡的,那么不通过" salience 10 no-loop true when $c:CreditCardApplyInfo(hasCar == false && hasHouse == false && education == CreditCardApplyInfo.EDUCATION_4 && monthlyIncome < 2000 && hasCreditCardCount == 0) then $c.setCheckResult(false); drools.halt();endrule "如果申请人现有的信用卡数量大于10,那么不通过" salience 10 no-loop true when $c:CreditCardApplyInfo(hasCreditCardCount > 10) then $c.setCheckResult(false); drools.halt();end//--------------------------------------------------------------------------//确定额度rule "如果申请人有房有车,或者月收入在20000以上,那么发放的信用卡额度为15000" salience 1 no-loop true activation-group "quota_group" when $c:CreditCardApplyInfo(checkResult == true && ((hasHouse == true && hasCar == true) || (monthlyIncome > 20000))) then $c.setQuota(15000);endrule "如果申请人没房没车,但月收入在10000~20000之间,那么发放的信用卡额度为6000" salience 1 no-loop true activation-group "quota_group" when $c:CreditCardApplyInfo(checkResult == true && hasHouse == false && hasCar == false && monthlyIncome >= 10000 && monthlyIncome <= 20000) then $c.setQuota(6000);endrule "如果申请人没房没车,月收入在10000以下,那么发放的信用卡额度为3000" salience 1 no-loop true activation-group "quota_group" when $c:CreditCardApplyInfo(checkResult == true && hasHouse == false && hasCar == false && monthlyIncome < 10000) then $c.setQuota(3000);endrule "如果申请人有房没车或者没房但有车,月收入在10000以下,那么发放的信用卡额度为5000" salience 1 no-loop true activation-group "quota_group" when $c:CreditCardApplyInfo(checkResult == true && ((hasHouse == true && hasCar == false) || (hasHouse == false && hasCar == true)) && monthlyIncome < 10000) then $c.setQuota(5000);endrule "如果申请人有房没车或者是没房但有车,月收入在10000~20000之间,那么发放的信用卡额度为8000" salience 1 no-loop true activation-group "quota_group" when $c:CreditCardApplyInfo(checkResult == true && ((hasHouse == true && hasCar == false) || (hasHouse == false && hasCar == true)) && monthlyIncome >= 10000 && monthlyIncome <= 20000) then $c.setQuota(8000);end<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>第六步:创建RuleService</p><pre class="line-numbers language-none"><code class="language-none">package com.itheima.drools.service;import com.itheima.drools.entity.CreditCardApplyInfo;import org.kie.api.KieBase;import org.kie.api.runtime.KieSession;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;@Servicepublic class RuleService { @Autowired private KieBase kieBase; //调用Drools规则引擎实现信用卡申请 public CreditCardApplyInfo creditCardApply(CreditCardApplyInfo creditCardApplyInfo){ KieSession session = kieBase.newKieSession(); session.insert(creditCardApplyInfo); session.fireAllRules(); session.dispose(); return creditCardApplyInfo; }}<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>第七步:创建RuleController</p><pre class="line-numbers language-none"><code class="language-none">package com.itheima.drools.controller;import com.itheima.drools.entity.CreditCardApplyInfo;import com.itheima.drools.service.RuleService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.RequestBody;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;@RestController@RequestMapping("/rule")public class RuleController { @Autowired private RuleService ruleService; @RequestMapping("/creditCardApply") public CreditCardApplyInfo creditCardApply(@RequestBody CreditCardApplyInfo creditCardApplyInfo){ creditCardApplyInfo = ruleService.creditCardApply(creditCardApplyInfo); return creditCardApplyInfo; }}<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>第八步:创建启动类DroolsApplication</p><pre class="line-numbers language-none"><code class="language-none">package com.itheima.drools;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplicationpublic class DroolsApplication { public static void main(String[] args) { SpringApplication.run(DroolsApplication.class); }}<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>第九步:导入静态资源文件到resources/static目录下</p><h3 id="9-3-保险产品准入规则-学到决策表这里-高级部分跳过"><a href="#9-3-保险产品准入规则-学到决策表这里-高级部分跳过" class="headerlink" title="9.3 保险产品准入规则 (学到决策表这里 高级部分跳过)"></a>9.3 保险产品准入规则 (学到决策表这里 高级部分跳过)</h3><h4 id="9-3-1-决策表"><a href="#9-3-1-决策表" class="headerlink" title="9.3.1 决策表"></a>9.3.1 决策表</h4><p>前面的课程中我们编写的规则文件都是drl形式的文件,Drools除了支持drl形式的文件外还支持xls格式的文件(即Excel文件)。这种xls格式的文件通常称为决策表(decision table)。</p><p>决策表(decision table)是一个“精确而紧凑的”表示条件逻辑的方式,非常适合商业级别的规则。决策表与现有的drl文件可以无缝替换。Drools提供了相应的API可以将xls文件编译为drl格式的字符串。</p><p>一个决策表的例子如下:</p><p><img src="/media/pictures/Drools.assets/image-20200217160930138.png" alt="image-20200217160930138"></p><p>决策表语法:</p><table><thead><tr><th align="left">关键字</th><th align="left">说明</th><th align="left">是否必须</th></tr></thead><tbody><tr><td align="left">RuleSet</td><td align="left">相当于drl文件中的package</td><td align="left">必须,只能有一个。如果没有设置RuleSet对应的值则使用默认值rule_table</td></tr><tr><td align="left">Sequential</td><td align="left">取值为Boolean类型。true表示规则按照表格自上到下的顺序执行,false表示乱序</td><td align="left">可选</td></tr><tr><td align="left">Import</td><td align="left">相当于drl文件中的import,如果引入多个类则类之间用逗号分隔</td><td align="left">可选</td></tr><tr><td align="left">Variables</td><td align="left">相当于drl文件中的global,用于定义全局变量,如果有多个全局变量则中间用逗号分隔</td><td align="left">可选</td></tr><tr><td align="left">RuleTable</td><td align="left">它指示了后面将会有一批rule,RuleTable的名称将会作为以后生成rule的前缀</td><td align="left">必须</td></tr><tr><td align="left">CONDITION</td><td align="left">规则条件关键字,相当于drl文件中的when。下面两行则表示 LHS 部分,第三行则为注释行,不计为规则部分,从第四行开始,每一行表示一条规则</td><td align="left">每个规则表至少有一个</td></tr><tr><td align="left">ACTION</td><td align="left">规则结果关键字,相当于drl文件中的then</td><td align="left">每个规则表至少有一个</td></tr><tr><td align="left">NO-LOOP</td><td align="left">相当于drl文件中的no-loop</td><td align="left">可选</td></tr><tr><td align="left">AGENDA-GROUP</td><td align="left">相当于drl文件中的agenda-group</td><td align="left">可选</td></tr></tbody></table><p>在决策表中还经常使用到占位符,语法为$后面加数字,用于替换每条规则中设置的具体值。</p><p>上面的决策表例子转换为drl格式的规则文件内容如下:</p><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">package</span> <span class="token namespace">rules</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">com<span class="token punctuation">.</span>itheima<span class="token punctuation">.</span>drools<span class="token punctuation">.</span>entity<span class="token punctuation">.</span></span><span class="token class-name">PersonInfoEntity</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">java<span class="token punctuation">.</span>util<span class="token punctuation">.</span></span><span class="token class-name">List</span><span class="token punctuation">;</span>global <span class="token class-name"><span class="token namespace">java<span class="token punctuation">.</span>util<span class="token punctuation">.</span></span>List</span> listRules<span class="token punctuation">;</span>rule <span class="token string">"personCheck_10"</span> salience <span class="token number">65535</span> agenda<span class="token operator">-</span>group <span class="token string">"sign"</span> when $person <span class="token operator">:</span> <span class="token class-name">PersonInfoEntity</span><span class="token punctuation">(</span>sex <span class="token operator">!=</span> <span class="token string">"男"</span><span class="token punctuation">)</span> then listRules<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token string">"性别不对"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>endrule <span class="token string">"personCheck_11"</span> salience <span class="token number">65534</span> agenda<span class="token operator">-</span>group <span class="token string">"sign"</span> when $person <span class="token operator">:</span> <span class="token class-name">PersonInfoEntity</span><span class="token punctuation">(</span>age <span class="token operator"><</span> <span class="token number">22</span> <span class="token operator">||</span> age <span class="token operator">></span> <span class="token number">25</span><span class="token punctuation">)</span> then listRules<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token string">"年龄不合适"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>endrule <span class="token string">"personCheck_12"</span> salience <span class="token number">65533</span> agenda<span class="token operator">-</span>group <span class="token string">"sign"</span> when $person <span class="token operator">:</span> <span class="token class-name">PersonInfoEntity</span><span class="token punctuation">(</span>salary <span class="token operator"><</span> <span class="token number">10000</span><span class="token punctuation">)</span> then listRules<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token string">"工资太低了"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>end<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>要进行决策表相关操作,需要导入如下maven坐标:</p><pre class="line-numbers language-xml" data-language="xml"><code class="language-xml"><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.drools<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>drools-decisiontables<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>7.10.0.Final<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>通过下图可以发现,由于maven的依赖传递特性在导入drools-decisiontables坐标后,drools-core和drools-compiler等坐标也被传递了过来</p><p><img src="/media/pictures/Drools.assets/image-20200218105819932.png" alt="image-20200218105819932"></p><p>Drools提供的将xls文件编译为drl格式字符串的API如下:</p><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token class-name">String</span> realPath <span class="token operator">=</span> <span class="token string">"C:\\testRule.xls"</span><span class="token punctuation">;</span><span class="token comment">//指定决策表xls文件的磁盘路径</span><span class="token class-name">File</span> file <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">File</span><span class="token punctuation">(</span>realPath<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token class-name">InputStream</span> is <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">FileInputStream</span><span class="token punctuation">(</span>file<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token class-name">SpreadsheetCompiler</span> compiler <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">SpreadsheetCompiler</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token class-name">String</span> drl <span class="token operator">=</span> compiler<span class="token punctuation">.</span><span class="token function">compile</span><span class="token punctuation">(</span>is<span class="token punctuation">,</span> <span class="token class-name">InputType</span><span class="token punctuation">.</span>XLS<span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>Drools还提供了基于drl格式字符串创建KieSession的API:</p><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token class-name">KieHelper</span> kieHelper <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">KieHelper</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>kieHelper<span class="token punctuation">.</span><span class="token function">addContent</span><span class="token punctuation">(</span>drl<span class="token punctuation">,</span> <span class="token class-name">ResourceType</span><span class="token punctuation">.</span>DRL<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token class-name">KieSession</span> session <span class="token operator">=</span> kieHelper<span class="token punctuation">.</span><span class="token function">build</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">newKieSession</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre><p>基于决策表的入门案例:</p><p>第一步:创建maven工程drools_decisiontable_demo并配置pom.xml文件</p><pre class="line-numbers language-xml" data-language="xml"><code class="language-xml"><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.drools<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>drools-decisiontables<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>7.10.0.Final<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>junit<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>junit<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>4.12<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>第二步:创建实体类PersonInfoEntity</p><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">package</span> <span class="token namespace">com<span class="token punctuation">.</span>itheima<span class="token punctuation">.</span>drools<span class="token punctuation">.</span>entity</span><span class="token punctuation">;</span><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">PersonInfoEntity</span> <span class="token punctuation">{</span> <span class="token keyword">private</span> <span class="token class-name">String</span> sex<span class="token punctuation">;</span> <span class="token keyword">private</span> <span class="token keyword">int</span> age<span class="token punctuation">;</span> <span class="token keyword">private</span> <span class="token keyword">double</span> salary<span class="token punctuation">;</span> <span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">getSex</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> sex<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setSex</span><span class="token punctuation">(</span><span class="token class-name">String</span> sex<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>sex <span class="token operator">=</span> sex<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">int</span> <span class="token function">getAge</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> age<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setAge</span><span class="token punctuation">(</span><span class="token keyword">int</span> age<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>age <span class="token operator">=</span> age<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">double</span> <span class="token function">getSalary</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> salary<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setSalary</span><span class="token punctuation">(</span><span class="token keyword">double</span> salary<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>salary <span class="token operator">=</span> salary<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>第三步:创建xls规则文件(可以直接使用资料中提供的testRule.xls文件)</p><p>第四步:创建单元测试</p><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token annotation punctuation">@Test</span><span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">test1</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">Exception</span><span class="token punctuation">{</span> <span class="token class-name">String</span> realPath <span class="token operator">=</span> <span class="token string">"d:\\testRule.xls"</span><span class="token punctuation">;</span><span class="token comment">//指定决策表xls文件的磁盘路径</span> <span class="token class-name">File</span> file <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">File</span><span class="token punctuation">(</span>realPath<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">InputStream</span> is <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">FileInputStream</span><span class="token punctuation">(</span>file<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">SpreadsheetCompiler</span> compiler <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">SpreadsheetCompiler</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">String</span> drl <span class="token operator">=</span> compiler<span class="token punctuation">.</span><span class="token function">compile</span><span class="token punctuation">(</span>is<span class="token punctuation">,</span> <span class="token class-name">InputType</span><span class="token punctuation">.</span>XLS<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>drl<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">KieHelper</span> kieHelper <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">KieHelper</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> kieHelper<span class="token punctuation">.</span><span class="token function">addContent</span><span class="token punctuation">(</span>drl<span class="token punctuation">,</span> <span class="token class-name">ResourceType</span><span class="token punctuation">.</span>DRL<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">KieSession</span> session <span class="token operator">=</span> kieHelper<span class="token punctuation">.</span><span class="token function">build</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">newKieSession</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">PersonInfoEntity</span> personInfoEntity <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">PersonInfoEntity</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> personInfoEntity<span class="token punctuation">.</span><span class="token function">setSex</span><span class="token punctuation">(</span><span class="token string">"男"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> personInfoEntity<span class="token punctuation">.</span><span class="token function">setAge</span><span class="token punctuation">(</span><span class="token number">35</span><span class="token punctuation">)</span><span class="token punctuation">;</span> personInfoEntity<span class="token punctuation">.</span><span class="token function">setSalary</span><span class="token punctuation">(</span><span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">List</span><span class="token generics"><span class="token punctuation"><</span><span class="token class-name">String</span><span class="token punctuation">></span></span> list <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ArrayList</span><span class="token generics"><span class="token punctuation"><</span><span class="token class-name">String</span><span class="token punctuation">></span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> session<span class="token punctuation">.</span><span class="token function">setGlobal</span><span class="token punctuation">(</span><span class="token string">"listRules"</span><span class="token punctuation">,</span>list<span class="token punctuation">)</span><span class="token punctuation">;</span> session<span class="token punctuation">.</span><span class="token function">insert</span><span class="token punctuation">(</span>personInfoEntity<span class="token punctuation">)</span><span class="token punctuation">;</span> session<span class="token punctuation">.</span><span class="token function">getAgenda</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getAgendaGroup</span><span class="token punctuation">(</span><span class="token string">"sign"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">setFocus</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> session<span class="token punctuation">.</span><span class="token function">fireAllRules</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token class-name">String</span> s <span class="token operator">:</span> list<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>s<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> session<span class="token punctuation">.</span><span class="token function">dispose</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h4 id="9-3-2-规则介绍"><a href="#9-3-2-规则介绍" class="headerlink" title="9.3.2 规则介绍"></a>9.3.2 规则介绍</h4><p>各保险公司针对人身、财产推出了不同的保险产品,作为商业保险公司,筛选出符合公司利益最大化的客户是非常重要的,即各保险产品的准入人群是不同的,也就是说保险公司会针对不同的人群特征,制定不同的产品缴费和赔付规则。</p><p>我们来看一下某保险产品准入规则的简化版,当不满足以下规则时,系统模块需要返回准入失败标识和失败原因</p><pre class="line-numbers language-none"><code class="language-none">规则1: 保险公司是:PICC规则2: 销售区域是:北京、天津规则3: 投保人年龄:0 ~ 17岁规则4: 保险期间是:20年、25年、30年规则5: 缴费方式是:趸交(一次性交清)或年交规则6: 保险期与交费期规则一:保险期间为20年期交费期间最长10年交且不能选择[趸交]规则7: 保险期与交费期规则二:保险期间为25年期交费期间最长15年交且不能选择[趸交]规则8: 保险期与交费期规则三:保险期间为30年期交费期间最长20年交且不能选择[趸交]规则9: 被保人要求:(投保年龄+保险期间)不得大于40周岁规则10: 保险金额规则:投保时约定,最低为5万元,超过部分必须为1000元的整数倍规则11: 出单基本保额限额规则:线上出单基本保额限额62.5万元,超62.5万元需配合契调转线下出单<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>在本案例中规则文件是一个Excel文件,业务人员可以直接更改这个文件中指标的值,系统不需要做任何变更。</p><h4 id="9-3-3-实现步骤"><a href="#9-3-3-实现步骤" class="headerlink" title="9.3.3 实现步骤"></a>9.3.3 实现步骤</h4><p>本案例还是基于Spring Boot整合Drools的架构来实现。</p><p>第一步:创建maven工程insuranceInfoCheck并配置pom.xml文件</p><pre class="line-numbers language-xml" data-language="xml"><code class="language-xml"><span class="token prolog"><?xml version="1.0" encoding="UTF-8"?></span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>project</span> <span class="token attr-name">xmlns</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>http://maven.apache.org/POM/4.0.0<span class="token punctuation">"</span></span> <span class="token attr-name"><span class="token namespace">xmlns:</span>xsi</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>http://www.w3.org/2001/XMLSchema-instance<span class="token punctuation">"</span></span> <span class="token attr-name"><span class="token namespace">xsi:</span>schemaLocation</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>modelVersion</span><span class="token punctuation">></span></span>4.0.0<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>modelVersion</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>parent</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-boot-starters<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>2.0.6.RELEASE<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>parent</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>com.itheima<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>insuranceInfoCheck<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>1.0-SNAPSHOT<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependencies</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-boot-starter-web<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-boot-starter-aop<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-boot-starter-test<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>commons-lang<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>commons-lang<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>2.6<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token comment"><!--drools规则引擎--></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.drools<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>drools-core<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>7.6.0.Final<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.drools<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>drools-compiler<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>7.6.0.Final<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.drools<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>drools-templates<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>7.6.0.Final<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.kie<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>kie-api<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>7.6.0.Final<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.kie<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>kie-spring<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>exclusions</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>exclusion</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-tx<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>exclusion</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>exclusion</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-beans<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>exclusion</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>exclusion</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-core<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>exclusion</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>exclusion</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-context<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>exclusion</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>exclusions</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>7.6.0.Final<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependencies</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>build</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>finalName</span><span class="token punctuation">></span></span>${project.artifactId}<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>finalName</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>resources</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>resource</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>directory</span><span class="token punctuation">></span></span>src/main/java<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>directory</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>includes</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>include</span><span class="token punctuation">></span></span>**/*.xml<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>include</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>includes</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>filtering</span><span class="token punctuation">></span></span>false<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>filtering</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>resource</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>resource</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>directory</span><span class="token punctuation">></span></span>src/main/resources<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>directory</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>includes</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>include</span><span class="token punctuation">></span></span>**/*.*<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>include</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>includes</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>filtering</span><span class="token punctuation">></span></span>false<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>filtering</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>resource</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>resources</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>plugins</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>plugin</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.apache.maven.plugins<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>maven-compiler-plugin<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>2.3.2<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>configuration</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>source</span><span class="token punctuation">></span></span>1.8<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>source</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>target</span><span class="token punctuation">></span></span>1.8<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>target</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>configuration</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>plugin</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>plugins</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>build</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>project</span><span class="token punctuation">></span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>第二步:创建/resources/application.yml文件</p><pre class="line-numbers language-none"><code class="language-none">server: port: 8080spring: application: name: insuranceInfoCheck<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>第三步:创建实体类InsuranceInfo</p><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">package</span> <span class="token namespace">com<span class="token punctuation">.</span>itheima<span class="token punctuation">.</span>drools<span class="token punctuation">.</span>entity</span><span class="token punctuation">;</span><span class="token comment">/** * 保险信息 */</span><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">InsuranceInfo</span> <span class="token punctuation">{</span> <span class="token keyword">private</span> <span class="token class-name">String</span> param1<span class="token punctuation">;</span><span class="token comment">//保险公司</span> <span class="token keyword">private</span> <span class="token class-name">String</span> param2<span class="token punctuation">;</span><span class="token comment">//方案代码</span> <span class="token keyword">private</span> <span class="token class-name">String</span> param3<span class="token punctuation">;</span><span class="token comment">//渠道号</span> <span class="token keyword">private</span> <span class="token class-name">String</span> param4<span class="token punctuation">;</span><span class="token comment">//销售区域</span> <span class="token keyword">private</span> <span class="token class-name">String</span> param5<span class="token punctuation">;</span><span class="token comment">//投保年龄</span> <span class="token keyword">private</span> <span class="token class-name">String</span> param6<span class="token punctuation">;</span><span class="token comment">//保险期间</span> <span class="token keyword">private</span> <span class="token class-name">String</span> param7<span class="token punctuation">;</span><span class="token comment">//缴费期间</span> <span class="token keyword">private</span> <span class="token class-name">String</span> param8<span class="token punctuation">;</span><span class="token comment">//缴费方式</span> <span class="token keyword">private</span> <span class="token class-name">String</span> param9<span class="token punctuation">;</span><span class="token comment">//保障类型</span> <span class="token keyword">private</span> <span class="token class-name">String</span> param10<span class="token punctuation">;</span><span class="token comment">//等待期</span> <span class="token keyword">private</span> <span class="token class-name">String</span> param11<span class="token punctuation">;</span><span class="token comment">//犹豫期</span> <span class="token keyword">private</span> <span class="token class-name">String</span> param12<span class="token punctuation">;</span><span class="token comment">//职业类型</span> <span class="token keyword">private</span> <span class="token class-name">String</span> param13<span class="token punctuation">;</span><span class="token comment">//保额限制</span> <span class="token keyword">private</span> <span class="token class-name">String</span> param14<span class="token punctuation">;</span><span class="token comment">//免赔额</span> <span class="token keyword">private</span> <span class="token class-name">String</span> param15<span class="token punctuation">;</span><span class="token comment">//主险保额</span> <span class="token keyword">private</span> <span class="token class-name">String</span> param16<span class="token punctuation">;</span><span class="token comment">//主险保费</span> <span class="token keyword">private</span> <span class="token class-name">String</span> param17<span class="token punctuation">;</span><span class="token comment">//附加险保额</span> <span class="token keyword">private</span> <span class="token class-name">String</span> param18<span class="token punctuation">;</span><span class="token comment">//附加险保费</span> <span class="token keyword">private</span> <span class="token class-name">String</span> param19<span class="token punctuation">;</span><span class="token comment">//与投保人关系</span> <span class="token keyword">private</span> <span class="token class-name">String</span> param20<span class="token punctuation">;</span><span class="token comment">//与被保人关系</span> <span class="token keyword">private</span> <span class="token class-name">String</span> param21<span class="token punctuation">;</span><span class="token comment">//性别</span> <span class="token keyword">private</span> <span class="token class-name">String</span> param22<span class="token punctuation">;</span><span class="token comment">//证件</span> <span class="token keyword">private</span> <span class="token class-name">String</span> param23<span class="token punctuation">;</span><span class="token comment">//保费</span> <span class="token keyword">private</span> <span class="token class-name">String</span> param24<span class="token punctuation">;</span><span class="token comment">//保额</span> <span class="token comment">//getter setter省略</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>第四步:创建决策表文件(也可以直接使用实战资料中提供的insuranceInfoCheck.xls文件)</p><p><img src="/media/pictures/Drools.assets/image-20200218120618384.png" alt="image-20200218120618384"></p><p>第五步:封装工具类KieSessionUtils</p><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">package</span> <span class="token namespace">com<span class="token punctuation">.</span>itheima<span class="token punctuation">.</span>drools<span class="token punctuation">.</span>utils</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">com<span class="token punctuation">.</span>itheima<span class="token punctuation">.</span>drools<span class="token punctuation">.</span>entity<span class="token punctuation">.</span></span><span class="token class-name">InsuranceInfo</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">com<span class="token punctuation">.</span>itheima<span class="token punctuation">.</span>drools<span class="token punctuation">.</span>entity<span class="token punctuation">.</span></span><span class="token class-name">PersonInfoEntity</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>drools<span class="token punctuation">.</span>decisiontable<span class="token punctuation">.</span></span><span class="token class-name">InputType</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>drools<span class="token punctuation">.</span>decisiontable<span class="token punctuation">.</span></span><span class="token class-name">SpreadsheetCompiler</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>kie<span class="token punctuation">.</span>api<span class="token punctuation">.</span>builder<span class="token punctuation">.</span></span><span class="token class-name">Message</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>kie<span class="token punctuation">.</span>api<span class="token punctuation">.</span>builder<span class="token punctuation">.</span></span><span class="token class-name">Results</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>kie<span class="token punctuation">.</span>api<span class="token punctuation">.</span>io<span class="token punctuation">.</span></span><span class="token class-name">ResourceType</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>kie<span class="token punctuation">.</span>api<span class="token punctuation">.</span>runtime<span class="token punctuation">.</span></span><span class="token class-name">KieSession</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>kie<span class="token punctuation">.</span>internal<span class="token punctuation">.</span>utils<span class="token punctuation">.</span></span><span class="token class-name">KieHelper</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">java<span class="token punctuation">.</span>io<span class="token punctuation">.</span></span><span class="token class-name">File</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">java<span class="token punctuation">.</span>io<span class="token punctuation">.</span></span><span class="token class-name">FileInputStream</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">java<span class="token punctuation">.</span>io<span class="token punctuation">.</span></span><span class="token class-name">FileNotFoundException</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">java<span class="token punctuation">.</span>io<span class="token punctuation">.</span></span><span class="token class-name">InputStream</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">java<span class="token punctuation">.</span>util<span class="token punctuation">.</span></span><span class="token class-name">ArrayList</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">java<span class="token punctuation">.</span>util<span class="token punctuation">.</span></span><span class="token class-name">List</span><span class="token punctuation">;</span><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">KieSessionUtils</span> <span class="token punctuation">{</span> <span class="token keyword">private</span> <span class="token class-name">KieSessionUtils</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token comment">// 把xls文件解析为String</span> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token class-name">String</span> getDRL <span class="token punctuation">(</span><span class="token class-name">String</span> realPath<span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">FileNotFoundException</span> <span class="token punctuation">{</span> <span class="token class-name">File</span> file <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">File</span><span class="token punctuation">(</span>realPath<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 例如:C:\\abc.xls</span> <span class="token class-name">InputStream</span> is <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">FileInputStream</span><span class="token punctuation">(</span>file<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">SpreadsheetCompiler</span> compiler <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">SpreadsheetCompiler</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">String</span> drl <span class="token operator">=</span> compiler<span class="token punctuation">.</span><span class="token function">compile</span><span class="token punctuation">(</span>is<span class="token punctuation">,</span> <span class="token class-name">InputType</span><span class="token punctuation">.</span>XLS<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>drl<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> drl<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// drl为含有内容的字符串</span> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token class-name">KieSession</span> <span class="token function">createKieSessionFromDRL</span><span class="token punctuation">(</span><span class="token class-name">String</span> drl<span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">Exception</span><span class="token punctuation">{</span> <span class="token class-name">KieHelper</span> kieHelper <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">KieHelper</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> kieHelper<span class="token punctuation">.</span><span class="token function">addContent</span><span class="token punctuation">(</span>drl<span class="token punctuation">,</span> <span class="token class-name">ResourceType</span><span class="token punctuation">.</span>DRL<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">Results</span> results <span class="token operator">=</span> kieHelper<span class="token punctuation">.</span><span class="token function">verify</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>results<span class="token punctuation">.</span><span class="token function">hasMessages</span><span class="token punctuation">(</span><span class="token class-name">Message<span class="token punctuation">.</span>Level</span><span class="token punctuation">.</span>WARNING<span class="token punctuation">,</span> <span class="token class-name">Message<span class="token punctuation">.</span>Level</span><span class="token punctuation">.</span>ERROR<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token class-name">List</span><span class="token generics"><span class="token punctuation"><</span><span class="token class-name">Message</span><span class="token punctuation">></span></span> messages <span class="token operator">=</span> results<span class="token punctuation">.</span><span class="token function">getMessages</span><span class="token punctuation">(</span><span class="token class-name">Message<span class="token punctuation">.</span>Level</span><span class="token punctuation">.</span>WARNING<span class="token punctuation">,</span> <span class="token class-name">Message<span class="token punctuation">.</span>Level</span><span class="token punctuation">.</span>ERROR<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token class-name">Message</span> message <span class="token operator">:</span> messages<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"Error: "</span><span class="token operator">+</span>message<span class="token punctuation">.</span><span class="token function">getText</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// throw new IllegalStateException("Compilation errors were found. Check the logs.");</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> kieHelper<span class="token punctuation">.</span><span class="token function">build</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">newKieSession</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// realPath为Excel文件绝对路径</span> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token class-name">KieSession</span> <span class="token function">getKieSessionFromXLS</span><span class="token punctuation">(</span><span class="token class-name">String</span> realPath<span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">Exception</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token function">createKieSessionFromDRL</span><span class="token punctuation">(</span><span class="token function">getDRL</span><span class="token punctuation">(</span>realPath<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>第六步:创建RuleService类</p><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">package</span> <span class="token namespace">com<span class="token punctuation">.</span>itheima<span class="token punctuation">.</span>drools<span class="token punctuation">.</span>service</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">com<span class="token punctuation">.</span>itheima<span class="token punctuation">.</span>drools<span class="token punctuation">.</span>entity<span class="token punctuation">.</span></span><span class="token class-name">InsuranceInfo</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">com<span class="token punctuation">.</span>itheima<span class="token punctuation">.</span>drools<span class="token punctuation">.</span>utils<span class="token punctuation">.</span></span><span class="token class-name">KieSessionUtils</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>kie<span class="token punctuation">.</span>api<span class="token punctuation">.</span>runtime<span class="token punctuation">.</span></span><span class="token class-name">KieSession</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>stereotype<span class="token punctuation">.</span></span><span class="token class-name">Service</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">java<span class="token punctuation">.</span>util<span class="token punctuation">.</span></span><span class="token class-name">ArrayList</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">java<span class="token punctuation">.</span>util<span class="token punctuation">.</span></span><span class="token class-name">List</span><span class="token punctuation">;</span><span class="token annotation punctuation">@Service</span><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">RuleService</span> <span class="token punctuation">{</span> <span class="token keyword">public</span> <span class="token class-name">List</span><span class="token generics"><span class="token punctuation"><</span><span class="token class-name">String</span><span class="token punctuation">></span></span> <span class="token function">insuranceInfoCheck</span><span class="token punctuation">(</span><span class="token class-name">InsuranceInfo</span> insuranceInfo<span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">Exception</span><span class="token punctuation">{</span> <span class="token class-name">KieSession</span> session <span class="token operator">=</span> <span class="token class-name">KieSessionUtils</span><span class="token punctuation">.</span><span class="token function">getKieSessionFromXLS</span><span class="token punctuation">(</span><span class="token string">"D:\\rules.xls"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> session<span class="token punctuation">.</span><span class="token function">getAgenda</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getAgendaGroup</span><span class="token punctuation">(</span><span class="token string">"sign"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">setFocus</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> session<span class="token punctuation">.</span><span class="token function">insert</span><span class="token punctuation">(</span>insuranceInfo<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">List</span><span class="token generics"><span class="token punctuation"><</span><span class="token class-name">String</span><span class="token punctuation">></span></span> listRules <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ArrayList</span><span class="token generics"><span class="token punctuation"><</span><span class="token punctuation">></span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> session<span class="token punctuation">.</span><span class="token function">setGlobal</span><span class="token punctuation">(</span><span class="token string">"listRules"</span><span class="token punctuation">,</span> listRules<span class="token punctuation">)</span><span class="token punctuation">;</span> session<span class="token punctuation">.</span><span class="token function">fireAllRules</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> listRules<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>第七步:创建RuleController类</p><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">package</span> <span class="token namespace">com<span class="token punctuation">.</span>itheima<span class="token punctuation">.</span>drools<span class="token punctuation">.</span>controller</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">com<span class="token punctuation">.</span>itheima<span class="token punctuation">.</span>drools<span class="token punctuation">.</span>entity<span class="token punctuation">.</span></span><span class="token class-name">InsuranceInfo</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">com<span class="token punctuation">.</span>itheima<span class="token punctuation">.</span>drools<span class="token punctuation">.</span>service<span class="token punctuation">.</span></span><span class="token class-name">RuleService</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>beans<span class="token punctuation">.</span>factory<span class="token punctuation">.</span>annotation<span class="token punctuation">.</span></span><span class="token class-name">Autowired</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>web<span class="token punctuation">.</span>bind<span class="token punctuation">.</span>annotation<span class="token punctuation">.</span></span><span class="token class-name">RequestMapping</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>web<span class="token punctuation">.</span>bind<span class="token punctuation">.</span>annotation<span class="token punctuation">.</span></span><span class="token class-name">RestController</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">java<span class="token punctuation">.</span>util<span class="token punctuation">.</span></span><span class="token class-name">HashMap</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">java<span class="token punctuation">.</span>util<span class="token punctuation">.</span></span><span class="token class-name">List</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">java<span class="token punctuation">.</span>util<span class="token punctuation">.</span></span><span class="token class-name">Map</span><span class="token punctuation">;</span><span class="token annotation punctuation">@RestController</span><span class="token annotation punctuation">@RequestMapping</span><span class="token punctuation">(</span><span class="token string">"/rule"</span><span class="token punctuation">)</span><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">RuleController</span> <span class="token punctuation">{</span> <span class="token annotation punctuation">@Autowired</span> <span class="token keyword">private</span> <span class="token class-name">RuleService</span> ruleService<span class="token punctuation">;</span> <span class="token annotation punctuation">@RequestMapping</span><span class="token punctuation">(</span><span class="token string">"/insuranceInfoCheck"</span><span class="token punctuation">)</span> <span class="token keyword">public</span> <span class="token class-name">Map</span> <span class="token function">insuranceInfoCheck</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token class-name">Map</span> map <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">HashMap</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//模拟数据,实际应为页面传递过来</span> <span class="token class-name">InsuranceInfo</span> insuranceInfo <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">InsuranceInfo</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> insuranceInfo<span class="token punctuation">.</span><span class="token function">setParam1</span><span class="token punctuation">(</span><span class="token string">"picc"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> insuranceInfo<span class="token punctuation">.</span><span class="token function">setParam4</span><span class="token punctuation">(</span><span class="token string">"上海"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> insuranceInfo<span class="token punctuation">.</span><span class="token function">setParam5</span><span class="token punctuation">(</span><span class="token string">"101"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> insuranceInfo<span class="token punctuation">.</span><span class="token function">setParam6</span><span class="token punctuation">(</span><span class="token string">"12"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> insuranceInfo<span class="token punctuation">.</span><span class="token function">setParam7</span><span class="token punctuation">(</span><span class="token string">"222"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> insuranceInfo<span class="token punctuation">.</span><span class="token function">setParam8</span><span class="token punctuation">(</span><span class="token string">"1"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> insuranceInfo<span class="token punctuation">.</span><span class="token function">setParam13</span><span class="token punctuation">(</span><span class="token string">"3"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">try</span> <span class="token punctuation">{</span> <span class="token class-name">List</span><span class="token generics"><span class="token punctuation"><</span><span class="token class-name">String</span><span class="token punctuation">></span></span> list <span class="token operator">=</span> ruleService<span class="token punctuation">.</span><span class="token function">insuranceInfoCheck</span><span class="token punctuation">(</span>insuranceInfo<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span><span class="token punctuation">(</span>list <span class="token operator">!=</span> <span class="token keyword">null</span> <span class="token operator">&&</span> list<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">></span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">{</span> map<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">"checkResult"</span><span class="token punctuation">,</span><span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span> map<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">"msg"</span><span class="token punctuation">,</span><span class="token string">"准入失败"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> map<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">"detail"</span><span class="token punctuation">,</span>list<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token keyword">else</span><span class="token punctuation">{</span> map<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">"checkResult"</span><span class="token punctuation">,</span><span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span> map<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">"msg"</span><span class="token punctuation">,</span><span class="token string">"准入成功"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> map<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token class-name">Exception</span> e<span class="token punctuation">)</span> <span class="token punctuation">{</span> e<span class="token punctuation">.</span><span class="token function">printStackTrace</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> map<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">"checkResult"</span><span class="token punctuation">,</span><span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span> map<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">"msg"</span><span class="token punctuation">,</span><span class="token string">"未知错误"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> map<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>第八步:创建启动类DroolsApplication</p><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">package</span> <span class="token namespace">com<span class="token punctuation">.</span>itheima<span class="token punctuation">.</span>drools</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>boot<span class="token punctuation">.</span></span><span class="token class-name">SpringApplication</span><span class="token punctuation">;</span><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>boot<span class="token punctuation">.</span>autoconfigure<span class="token punctuation">.</span></span><span class="token class-name">SpringBootApplication</span><span class="token punctuation">;</span><span class="token annotation punctuation">@SpringBootApplication</span><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">DroolsApplication</span> <span class="token punctuation">{</span> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token class-name">String</span><span class="token punctuation">[</span><span class="token punctuation">]</span> args<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token class-name">SpringApplication</span><span class="token punctuation">.</span><span class="token function">run</span><span class="token punctuation">(</span><span class="token class-name">DroolsApplication</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>]]></content>
<categories>
<category> JAVA </category>
</categories>
<tags>
<tag> Java </tag>
<tag> Drools </tag>
</tags>
</entry>
<entry>
<title>MySQL数据库使用规范</title>
<link href="/2022/01/17/mysql-shu-ju-ku-shi-yong-gui-fan/"/>
<url>/2022/01/17/mysql-shu-ju-ku-shi-yong-gui-fan/</url>
<content type="html"><![CDATA[<p>根据原公司规范、阿里巴巴JAVA规范、58到家MySQL军规合成</p><h3 id="MySQL数据库使用规范"><a href="#MySQL数据库使用规范" class="headerlink" title="MySQL数据库使用规范"></a>MySQL数据库使用规范</h3><h4 id="一、建表规约"><a href="#一、建表规约" class="headerlink" title="一、建表规约"></a>一、建表规约</h4><ol><li>【强制】数据库名、表名、字段名统一使用小写,多单词统一使用下划线分割<br> 说明:表名大小写是否敏感可修改数据库参数lower_case_table_names控制,但建议数据库建好后此类参数不可变更</li><li>【强制】表达是与否概念的字段,必须使用 is_xxx 的方式命名,数据类型是 unsigned tinyint(1 表示是,0 表示否)</li><li>【强制】禁用保留字,如 desc、range、match、delayed 等,请参考 MySQL 官方保留字</li><li>【强制】主键索引名为<code> pk_字段名</code>;唯一索引名为 <code>uk_字段名</code>;普通索引名则为<code> idx_字段名</code></li><li>【强制】小数类型为 decimal,禁止使用 float 和 double<br> 说明:在存储的时候,float 和 double 都存在精度损失的问题,很可能在比较值的时候,得到不正确的结果。如果存储的数据范围超过 decimal 的范围,建议将数据拆成整数和小数并分开存储</li><li>【强制】如果存储的字符串长度能够确定完全相等,使用 char 定长字符串类型</li><li>【强制】varchar 是可变长字符串,不预先分配存储空间,长度不要超过 5000,如果存储长度大于此值,定义字段类型为 text,独立出来一张表,用主键来对应,避免影响其它字段索引效率</li><li>【可选】表必备三字段:id, create_time, update_time<br> 说明:其中 id 必为主键,单表时自增、步长为 1。create_time, update_time的类型均为 datetime 类型,前者现在时表示主动式创建,后者过去分词表示被动式更新</li><li>【可选】尽量避免使用timestamp,timestamp数据最大值北京时间2038-01-19 11:14:07</li><li>【强制】一张表中只能有一个字段定义为ON UPDATE CURRENT_TIMESTAMP<br>说明:MySQL 5.6之前一张表只能有一列自动更新时间列;5.7以后支持多列,但如果定义了多列,只有最前面的那一列才会自动更新时间</li><li>【可选】表中业务字段尽量不要用timestamp,可用datetime代替,原因见第9点</li><li>【推荐】表的命名最好是遵循<code>业务名称_表的作用</code></li><li>【推荐】单表行数超过 500 万行或者单表容量超过 2GB,才推荐进行分库分表</li><li>【推荐】建库、建表字符编码尽量使用utf8mb4</li><li>【强制】临时表必须以<code>tmp_</code>开头、以日期结尾,备份表必须以<code>bak_</code>开头、以日期结尾</li><li>【强制】避免使用ENUM类型<br>说明:修改ENUM值需要使用ALTER语句;ENUM类型的ORDER BY操作效率低,需要额外操作</li></ol><h4 id="二、索引规约"><a href="#二、索引规约" class="headerlink" title="二、索引规约"></a>二、索引规约</h4><ol><li>【强制】业务上具有唯一特性的字段,即使是组合字段,也必须建成唯一索引<br>说明:不要以为唯一索引影响了 insert 速度,这个速度损耗可以忽略,但提高查找速度是明显的;另外,即使在应用层做了非常完善的校验控制,只要没有唯一索引,根据墨菲定律,必然有脏数据产生</li><li>【强制】页面搜索严禁左模糊或者全模糊</li><li>【推荐】如果有 order by 的场景,请注意利用索引的有序性。order by 最后的字段是组合索引的一部分,并且放在索引组合顺序的最后,避免出现 file_sort 的情况,影响查询性能。<br>正例:where a=? and b=? order by c; 索引:a_b_c<br>反例:索引如果存在范围查询,那么索引有序性无法利用,如:WHERE a>10 ORDER BY b; 索引 a_b 无法排序</li><li>【推荐】利用延迟关联或者子查询优化超多分页场景<br>说明:MySQL 并不是跳过 offset 行,而是取 offset+N 行,然后返回放弃前 offset 行,返回 N 行,那当offset 特别大的时候,效率就非常的低下,要么控制返回的总页数,要么对超过特定阈值的页数进行 SQL改写<br>正例:先快速定位需要获取的 id 段,然后再关联:<pre class="line-numbers language-none"><code class="language-none">SELECT t1.* FROM 表 1 as t1, (select id from 表 1 where 条件 LIMIT 100000,20 ) as t2 where t1.id=t2.id<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre></li><li>【推荐】SQL 性能优化的目标:至少要达到 range 级别,要求是 ref 级别,如果可以是 consts最好<br>说明:<br>1) consts 单表中最多只有一个匹配行(主键或者唯一索引),在优化阶段即可读取到数据。<br>2) ref 指的是使用普通的索引(normal index)。<br>3) range 对索引进行范围检索。<br>反例:explain 表的结果,type=index,索引物理文件全扫描,速度非常慢,这个 index 级别比range还低,与全表扫描是小巫见大巫</li><li>【推荐】建组合索引的时候,区分度最高的在最左边<br>正例:如果 where a=? and b=?,a 列的几乎接近于唯一值,那么只需要单建 idx_a 索引即可<br>说明:存在非等号和等号混合判断条件时,在建索引时,请把等号条件的列前置。如:where c>? and d=? 那么即使 c 的区分度更高,也必须把 d 放在索引的最前列,即建立组合索引 idx_d_c</li><li>【推荐】防止因字段类型不同造成的隐式转换,导致索引失效</li></ol><h4 id="三、SQL语句"><a href="#三、SQL语句" class="headerlink" title="三、SQL语句"></a>三、SQL语句</h4><ol><li>【推荐】不要使用 count(列名)或 count(常量)来替代 count(<em>),count(</em>)是 SQL92 定义的标准统计行数的语法,跟数据库无关,跟 NULL 和非 NULL 无关<br>说明:<code>count(*)</code>会统计值为 NULL 的行,而 count(列名)不会统计此列为 NULL 值的行</li><li>【强制】count(distinct col) 计算该列除 NULL 之外的不重复行数,注意 count(distinct col1, col2) 如果其中一列全为 NULL,那么即使另一列有不同的值,也返回为 0</li><li>【强制】当某一列的值全是 NULL 时,count(col)的返回结果为 0,但 sum(col)的返回结果为NULL,因此使用 sum()时需注意 NPE 问题<br>正例:可以使用如下方式来避免 sum 的 NPE 问题:SELECT IFNULL(SUM(column), 0) FROM table</li><li>【强制】使用 ISNULL()来判断是否为 NULL 值<br>说明:NULL 与任何值的直接比较都为 NULL</li><li>【强制】禁止使用存储过程,存储过程难以调试和扩展,更没有移植性</li><li>【推荐】in 操作能避免则避免,若实在避免不了,需要仔细评估 in 后边的集合元素数量,控制在 1000 个之内</li><li>【参考】TRUNCATE TABLE 比 DELETE 速度快,且使用的系统和事务日志资源少,但 TRUNCATE无事务且不触发 trigger,有可能造成事故,故不建议在开发代码中使用此语句</li><li>【强制】delete、update等SQL语句中必须包含where条件,减小数据影响范围</li><li>【推荐】尽量避免使用子查询,可以把子查询优化为join操作<br> 说明:<ul><li>子查询的结果集无法使用索引,通常子查询的结果集会被存储到临时表中,不论是内存临时表还是磁盘临时表都不会存在索引,所以查询性能会受到一定的影响</li><li>特别是对于返回结果集比较大的子查询,其对查询性能的影响也就越大</li><li>由于子查询会产生大量的临时表也没有索引,所以会消耗过多的CPU和IO资源,产生大量的慢查询</li></ul></li><li>【推荐】WHERE从句中尽量不要对列进行函数转换和计算,可以通过程序中转换后通过参数传入<br>正例:where create_time >= ‘20220101’ and create_time < ‘20220102’<br>反例:where date(create_time)=’20220101’</li><li>【推荐】在明显不会有重复值时使用UNION ALL而不是UNION<br>说明:<ul><li>UNION会把两个结果集的所有数据放到临时表中后再进行去重操作</li><li>UNION ALL不会再对结果集进行去重操作</li></ul></li><li>【推荐】拆分复杂的大SQL为多个小SQL<br>说明:<ul><li>大SQL在逻辑上比较复杂,需要占用大量CPU进行计算的SQL</li><li>SQL拆分后可以通过并行执行来提高处理效率</li></ul></li><li>【强制】超100万行的批量写(UPDATE、DELETE、INSERT)操作,必须要分批多次进行操作<br>说明:<ul><li>binlog日志为row格式时会产生大量的日志</li><li>容易产生大事务操作</li><li>binlog日志为row格式时会产生大量的日志</li></ul></li><li>【推荐】数据量超过50万时,尽可能使用NOT EXIST替代NOT IN</li></ol><h4 id="四、ORM映射"><a href="#四、ORM映射" class="headerlink" title="四、ORM映射"></a>四、ORM映射</h4><ol><li>【强制】在表查询中,一律不要使用 * 作为查询的字段列表,需要哪些字段必须明确写明<br> 说明:<ul><li>增加查询分析器解析成本。</li><li>增减字段容易与 resultMap 配置不一致</li><li>无用字段增加网络消耗,尤其是 text 类型的字段</li></ul></li><li>【推荐】sql.xml 配置参数尽量使用#{},尽量不要使用${}, 此种方式容易出现 SQL 注入,如果要使用也需要做拼接校验</li></ol><h4 id="五、其他"><a href="#五、其他" class="headerlink" title="五、其他"></a>五、其他</h4><ol><li>【推荐】写好的SQL,习惯性地explain查看执行计划</li><li>【推荐】不建议使用外键约束(foreign key)</li><li>【推荐】建议使用预编译语句进行数据库操作</li><li>【推荐】程序连接不同的数据库使用不同的账号<br>说明:为数据库迁移和分库分表留出余地;降低业务耦合度;避免权限过大而产生的安全风险</li></ol>]]></content>
<categories>
<category> 数据库 </category>
</categories>
<tags>
<tag> MySQL </tag>
<tag> 规范 </tag>
</tags>
</entry>
<entry>
<title>Redis使用规范</title>
<link href="/2022/01/07/redis-shi-yong-gui-fan/"/>
<url>/2022/01/07/redis-shi-yong-gui-fan/</url>
<content type="html"><![CDATA[<p>根据日常在使用redis时形成的,欢迎大家补充</p><h1 id="Redis使用规范"><a href="#Redis使用规范" class="headerlink" title="Redis使用规范"></a>Redis使用规范</h1><h4 id="一、key、value规范"><a href="#一、key、value规范" class="headerlink" title="一、key、value规范"></a>一、key、value规范</h4><ol><li>【强制】必须以业务名(或数据库名)为前缀,用冒号:分隔,比如 业务名:表名:id</li><li>【强制】key设计必须简洁<ul><li>保证语义的前提下,控制key的长度,当key较多时,内存占用也不容忽视。</li><li>不要包含特殊字符:空格、换行、单双引号以及其他转义字符</li></ul></li><li>【强制】string类型控制在10KB以内<br>说明:防止网卡流量、慢查询</li><li>【推荐】hash、list、set、zset元素个数不要超过1万。如果数量过大,可以分成多个key</li><li>【推荐】不要使用del删除非字符串的bigkey, 使用hscan、sscan、zscan方式渐进式删除<br>说明:因为时间复杂度是 O(N), hscan、sscan、zscan方式渐进式删除<ul><li>如果是Hash类型的大Key,推荐使用hscan + hdel</li><li>如果是List类型的大Key,推荐使用ltrim</li><li>如果是Set类型的大Key,推荐使用sscan + srem</li><li>如果是SortedSet类型的大Key,推荐使用zscan + zrem</li></ul></li><li>【推荐】尽量设置过期时间<br>说明:条件允许可以打散过期时间,防止集中过期,不过期的数据重点关注idletime。遇到大bigkey 过期,会触发del,造成主线程阻塞</li></ol><h4 id="二、命令规范"><a href="#二、命令规范" class="headerlink" title="二、命令规范"></a>二、命令规范</h4><ol><li>【强制】禁用keys<br>说明:Keys 命令效率极低,属于 O(N)操作,会阻塞其他正常命令,在 cluster 上,会是灾难性的操作</li><li>【强制】禁用flushall、flushdb<br>说明:命令会清空所有数据,属于高危操作</li><li>【强制】严禁对 zset 的不设范围操作</li><li>【强制】ZRANGE、 ZRANGEBYSCORE等多个操作 ZSET 的函数,严禁使用 ZRANGE myzset 0 -1 等这种不设置范围的操作。如要使用请指定范围,如 ZRANGE myzset 0 100。如不确定长度,可使用 ZCARD 判断长度</li><li>【强制】严禁对大数据量 Key 使用 HGETALL</li><li>【推荐】谨慎使用 sunion, sinter, sdiff等一些聚合操作,如果要用,需要提前报备</li></ol><h4 id="三、其他使用要求"><a href="#三、其他使用要求" class="headerlink" title="三、其他使用要求"></a>三、其他使用要求</h4><ol><li>【推荐】必要情况下可以使用monitor命令,但在生产上要注意不要长时间使用</li><li>【推荐】redis实例默认支持16个数据库,可以把不同的业务分到不同的库。但尽量不是切换库(即select库),如果需要跨库的通过key名来处理</li><li>【推荐】 如果有批量操作,优先使用mget、mset或pipeline,提高效率,但要注意控制一次批量操作的元素个数</li><li>【强制】不要在lua脚本中使用比较耗时的代码,比如长时间的sleep、大循环等, lua脚本的执行超时时间为5秒钟</li><li>【推荐】只用来保存热数据,不准当作落地数据库使用,即redis中的数据需要在其他数据库中查询到</li></ol><h4 id="四、集群使用"><a href="#四、集群使用" class="headerlink" title="四、集群使用"></a>四、集群使用</h4><p>Redis集群版本在使用Lua上有特殊要求</p><ol><li>【强制】所有key都应该由 KEYS 数组来传递,redis.call/pcall 里面调用的redis命令,key的位置,必须是KEYS array, 否则直接返回error,”-ERR bad lua script for redis cluster, all the keys that the script uses should be passed using the KEYS array”</li><li>【强制】所有key,必须在1个slot上,否则直接返回error, “-ERR eval/evalsha command keys must in same slot”<br>说明:redis在使用hash算法将键映射到slot时,只会计算{}里面的内容,若{}内的内容相同,则将键映射到同一个slot</li></ol><h4 id="五、代码使用"><a href="#五、代码使用" class="headerlink" title="五、代码使用"></a>五、代码使用</h4><ol><li>【推荐】value为string时,序列化尽量少采用JDK自带的序列化方式(JdkSerializationRedisSerializer),因为序列化速度慢</li><li>【强制】目前已经提供puzzle-cache公共组件,开发过程中尽量使用此组件,统一序列化方式</li><li>【强制】同一工程中,由统一的类保管key,不准在业务类中私自定义key</li></ol>]]></content>
<categories>
<category> 数据库 </category>
</categories>
<tags>
<tag> 规范 </tag>
<tag> Redis </tag>
</tags>
</entry>
<entry>
<title>中台的总结</title>
<link href="/2021/05/26/zhong-tai-de-zong-jie/"/>
<url>/2021/05/26/zhong-tai-de-zong-jie/</url>
<content type="html"><![CDATA[<p>原公司结合业态搭建了一套商城的业务中台,有了这套中台后可以快速启动一个新的应用应对市场的多变和公司业态的扩展,对此结合网上文档、视频总结的一些看法</p><h2 id="中台价值"><a href="#中台价值" class="headerlink" title="中台价值"></a>中台价值</h2><p>中台是一种组织心智,也是一种经营理念,提供公司的组织效率、协同效率、运营效率</p><h2 id="中台总结"><a href="#中台总结" class="headerlink" title="中台总结"></a>中台总结</h2><ol><li>中台并不总是能够提炼共性需求<br> 1.1 中台和业务方天然存在共性需求的不同诉求,比如一个新的需求,中台开始会认为不是共性需求,因为是新提出来的,而业务方认为这个可以提炼成一些共性需求,一个新需求很难判断为是否是共性需求。如果先按特性需求,可能会先开发,然后其他业务方提出来后又提炼成共性需求。</li><li>中台抱大业务的大腿,小业务抱大业务大腿<br> 2.1 业务会分优先级,中台优先满足大业务<br> 2.2 中台的KPI只能通过大业务实现<br> 2.3 小业务之痛,“你这个需求不通用,不满足共性”</li><li>中台的轮子也会变化,业务被动升级<br> 3.1 中台系统的架构和接口需要不断演进。如果<br> 3.2 先特性再共性,老业务已有功能需要切换<br> 3.3 业务被动升级,升级频率比自己独立发展要高</li><li>中台是某类业务的中台,不是所有业务的中台<br> 4.1 业务相似才有共性需求,业务差异越大中台价值越小</li><li>要把架构、接口、模型统一</li></ol><h2 id="中台、平台区别"><a href="#中台、平台区别" class="headerlink" title="中台、平台区别"></a>中台、平台区别</h2><p>平台是和业务无关的<br>中台将业务里面共性抽取出来,形成业务的服务</p><h2 id="中台、微服务区别"><a href="#中台、微服务区别" class="headerlink" title="中台、微服务区别"></a>中台、微服务区别</h2><p>中台可以通过微服务去实现,微服务可以通过架构去实现,中台是一种组织上的概念</p><h2 id="中台建议"><a href="#中台建议" class="headerlink" title="中台建议"></a>中台建议</h2><ol><li>先做好<code>技术平台</code></li><li>中台不是银弹。至少有超过3个相似平行的业务线才考虑中台</li><li>不要一开始就做一个大而全的平台,先找一个子域试点;不要试图做一个满足所有业务线的中台</li><li>中台的领导要和业务线同级别的高层,不然要成为业务线的外包团队</li><li>做好中台的资源投入统计和分析,这个很验评估</li></ol>]]></content>
<categories>
<category> 架构 </category>
</categories>
<tags>
<tag> 中台 </tag>
</tags>
</entry>
</search>