springbootAI 1.8.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (175) hide show
  1. spring/__init__.py +66 -0
  2. spring/ai/__init__.py +78 -0
  3. spring/ai/advisors.py +139 -0
  4. spring/ai/annotations.py +74 -0
  5. spring/ai/autoconfig.py +481 -0
  6. spring/ai/core.py +391 -0
  7. spring/ai/etl.py +188 -0
  8. spring/ai/memory.py +109 -0
  9. spring/ai/observability.py +129 -0
  10. spring/ai/providers.py +789 -0
  11. spring/ai/resilience.py +258 -0
  12. spring/ai/tools.py +106 -0
  13. spring/ai/vectorstore.py +303 -0
  14. spring/annotations/__init__.py +188 -0
  15. spring/annotations/cache.py +126 -0
  16. spring/annotations/cloud.py +207 -0
  17. spring/annotations/conditional.py +272 -0
  18. spring/annotations/core.py +864 -0
  19. spring/annotations/messaging.py +107 -0
  20. spring/aop/__init__.py +4 -0
  21. spring/aop/cloud_aop.py +404 -0
  22. spring/aop/comprehensive_aop.py +1015 -0
  23. spring/aop/method_interceptor.py +19 -0
  24. spring/aop/proxy_factory.py +55 -0
  25. spring/cloud/__init__.py +76 -0
  26. spring/cloud/discovery.py +364 -0
  27. spring/cloud/feign.py +469 -0
  28. spring/cloud/gateway.py +452 -0
  29. spring/cloud/load_balancer.py +149 -0
  30. spring/cloud/seata.py +557 -0
  31. spring/cloud/sentinel.py +525 -0
  32. spring/cloud/tracer.py +337 -0
  33. spring/config/__init__.py +21 -0
  34. spring/config/binding.py +206 -0
  35. spring/config/config_loader.py +405 -0
  36. spring/context/__init__.py +13 -0
  37. spring/context/application_context.py +589 -0
  38. spring/context/bean_definition.py +70 -0
  39. spring/context/bean_factory.py +1052 -0
  40. spring/context/registry.py +58 -0
  41. spring/context/scanner.py +106 -0
  42. spring/core/__init__.py +3 -0
  43. spring/core/graceful_shutdown.py +196 -0
  44. spring/core/typing_utils.py +50 -0
  45. spring/csv/__init__.py +52 -0
  46. spring/csv/annotations.py +402 -0
  47. spring/csv/converters.py +69 -0
  48. spring/csv/easy_csv.py +95 -0
  49. spring/csv/exceptions.py +27 -0
  50. spring/csv/reader.py +195 -0
  51. spring/csv/writer.py +155 -0
  52. spring/data/__init__.py +54 -0
  53. spring/data/page.py +181 -0
  54. spring/data/repository.py +274 -0
  55. spring/data/specification.py +228 -0
  56. spring/datasource/__init__.py +66 -0
  57. spring/datasource/annotations.py +133 -0
  58. spring/datasource/context.py +69 -0
  59. spring/datasource/dynamic.py +148 -0
  60. spring/event/__init__.py +7 -0
  61. spring/event/publisher.py +69 -0
  62. spring/excel/__init__.py +51 -0
  63. spring/excel/annotations.py +405 -0
  64. spring/excel/converters.py +231 -0
  65. spring/excel/easy_excel.py +94 -0
  66. spring/excel/exceptions.py +31 -0
  67. spring/excel/reader.py +254 -0
  68. spring/excel/style.py +95 -0
  69. spring/excel/writer.py +197 -0
  70. spring/i18n/__init__.py +97 -0
  71. spring/i18n/accessor.py +94 -0
  72. spring/i18n/auto_config.py +177 -0
  73. spring/i18n/holder.py +106 -0
  74. spring/i18n/locale.py +152 -0
  75. spring/i18n/locale_resolver.py +367 -0
  76. spring/i18n/message_source.py +250 -0
  77. spring/i18n/middleware.py +79 -0
  78. spring/i18n/properties.py +168 -0
  79. spring/i18n/sources.py +255 -0
  80. spring/logging/__init__.py +1 -0
  81. spring/logging/loguru_logger.py +228 -0
  82. spring/main.py +378 -0
  83. spring/messaging/__init__.py +1 -0
  84. spring/messaging/rabbitmq.py +302 -0
  85. spring/monitoring/__init__.py +1 -0
  86. spring/monitoring/prometheus.py +199 -0
  87. spring/orm/__init__.py +258 -0
  88. spring/orm/database.py +222 -0
  89. spring/orm/ddl_auto.py +1217 -0
  90. spring/orm/migration.py +419 -0
  91. spring/orm/mybatis_integration.py +400 -0
  92. spring/orm/pymybatis/__init__.py +86 -0
  93. spring/orm/pymybatis/annotations/__init__.py +30 -0
  94. spring/orm/pymybatis/annotations/annotations.py +332 -0
  95. spring/orm/pymybatis/cache/__init__.py +47 -0
  96. spring/orm/pymybatis/cache/cache.py +371 -0
  97. spring/orm/pymybatis/cache/redis_cache.py +434 -0
  98. spring/orm/pymybatis/circuit_breaker/__init__.py +21 -0
  99. spring/orm/pymybatis/circuit_breaker/circuit_breaker.py +424 -0
  100. spring/orm/pymybatis/configuration.py +525 -0
  101. spring/orm/pymybatis/core/__init__.py +10 -0
  102. spring/orm/pymybatis/core/sql_session.py +1382 -0
  103. spring/orm/pymybatis/core/sql_session_factory.py +76 -0
  104. spring/orm/pymybatis/dialect/__init__.py +9 -0
  105. spring/orm/pymybatis/dialect/dialect.py +445 -0
  106. spring/orm/pymybatis/dynamic_sql/__init__.py +9 -0
  107. spring/orm/pymybatis/dynamic_sql/dynamic_sql.py +900 -0
  108. spring/orm/pymybatis/interceptor/__init__.py +31 -0
  109. spring/orm/pymybatis/interceptor/interceptor.py +427 -0
  110. spring/orm/pymybatis/mapper/__init__.py +9 -0
  111. spring/orm/pymybatis/mapper/mapper.py +540 -0
  112. spring/orm/pymybatis/metrics/__init__.py +41 -0
  113. spring/orm/pymybatis/metrics/metrics.py +595 -0
  114. spring/orm/pymybatis/pool/__init__.py +9 -0
  115. spring/orm/pymybatis/pool/connection_pool.py +711 -0
  116. spring/orm/pymybatis/security/__init__.py +19 -0
  117. spring/orm/pymybatis/security/access_control.py +415 -0
  118. spring/orm/pymybatis/security/password_encoder.py +293 -0
  119. spring/orm/pymybatis/security/sensitive_data_masker.py +326 -0
  120. spring/orm/pymybatis/security/sql_injection_detector.py +675 -0
  121. spring/orm/pymybatis/transaction/__init__.py +9 -0
  122. spring/orm/pymybatis/transaction/transaction.py +288 -0
  123. spring/orm/pymybatis/type_handler/__init__.py +37 -0
  124. spring/orm/pymybatis/type_handler/type_handler.py +473 -0
  125. spring/orm/pymybatis/version.py +9 -0
  126. spring/orm/pymybatis/xml_parser/__init__.py +9 -0
  127. spring/orm/pymybatis/xml_parser/xml_parser.py +761 -0
  128. spring/retry/__init__.py +12 -0
  129. spring/retry/retry_annotations.py +71 -0
  130. spring/retry/retry_decorator.py +155 -0
  131. spring/scheduling/__init__.py +3 -0
  132. spring/scheduling/scheduler.py +389 -0
  133. spring/security/__init__.py +39 -0
  134. spring/security/jwt_utils.py +281 -0
  135. spring/security/replay_protection.py +206 -0
  136. spring/security/secret_manager.py +226 -0
  137. spring/security/security_aop.py +248 -0
  138. spring/security/security_context.py +172 -0
  139. spring/test/__init__.py +45 -0
  140. spring/test/slicing.py +341 -0
  141. spring/tracing/__init__.py +11 -0
  142. spring/tracing/skywalking.py +229 -0
  143. spring/tx/__init__.py +52 -0
  144. spring/tx/events.py +172 -0
  145. spring/tx/synchronization.py +143 -0
  146. spring/utils/__init__.py +5 -0
  147. spring/utils/banner.py +32 -0
  148. spring/utils/logger.py +73 -0
  149. spring/utils/redis_client.py +526 -0
  150. spring/validation/__init__.py +55 -0
  151. spring/validation/aop.py +141 -0
  152. spring/validation/constraints.py +357 -0
  153. spring/validation/exceptions.py +55 -0
  154. spring/validation/validator.py +139 -0
  155. spring/web/__init__.py +12 -0
  156. spring/web/actuator.py +319 -0
  157. spring/web/exception_handler.py +61 -0
  158. spring/web/health.py +399 -0
  159. spring/web/interceptor.py +91 -0
  160. spring/web/result.py +44 -0
  161. spring/web/swagger.py +601 -0
  162. spring/web/web_context.py +755 -0
  163. spring/websocket/__init__.py +86 -0
  164. spring/websocket/annotations.py +169 -0
  165. spring/websocket/broker.py +238 -0
  166. spring/websocket/exceptions.py +26 -0
  167. spring/websocket/handler.py +243 -0
  168. spring/websocket/router.py +526 -0
  169. spring/websocket/session.py +216 -0
  170. springbootai-1.8.0.dist-info/METADATA +2796 -0
  171. springbootai-1.8.0.dist-info/RECORD +175 -0
  172. springbootai-1.8.0.dist-info/WHEEL +5 -0
  173. springbootai-1.8.0.dist-info/entry_points.txt +2 -0
  174. springbootai-1.8.0.dist-info/licenses/LICENSE +7 -0
  175. springbootai-1.8.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,371 @@
1
+ """
2
+ PyMyBatis缓存模块
3
+
4
+ 实现多层次缓存机制:
5
+ 1. XML解析缓存:项目启动仅解析一次XML,后续直接读取内存缓存
6
+ 2. 预编译SQL缓存:相同SQL语句缓存prepare对象,避免重复编译
7
+ 3. 二级缓存:单表查询结果内存缓存,支持过期时间、刷新机制
8
+ """
9
+
10
+ import time
11
+ import hashlib
12
+ import logging
13
+ from typing import Dict, Any, Optional, List
14
+ from enum import Enum
15
+ from abc import abstractmethod
16
+
17
+ logger = logging.getLogger(__name__)
18
+
19
+
20
+ class CacheType(Enum):
21
+ """缓存类型"""
22
+ LRU = 'lru' # 最近最少使用
23
+ FIFO = 'fifo' # 先进先出
24
+ LFU = 'lfu' # 最不经常使用
25
+
26
+
27
+ class CacheEntry:
28
+ """缓存条目"""
29
+
30
+ def __init__(self, key: str, value: Any, ttl: int, access_counter: int = 0):
31
+ self.key = key
32
+ self.value = value
33
+ self.ttl = ttl
34
+ self.created_at = time.time()
35
+ self.access_count = 0
36
+ self.last_accessed = time.time()
37
+ self.access_counter = access_counter # 单调递增的访问计数器
38
+
39
+ def is_expired(self) -> bool:
40
+ """检查缓存是否过期"""
41
+ if self.ttl <= 0:
42
+ return False
43
+ return time.time() - self.created_at > self.ttl
44
+
45
+ def touch(self, counter: int = 0):
46
+ """更新访问时间和计数"""
47
+ self.access_count += 1
48
+ self.last_accessed = time.time()
49
+ if counter > 0:
50
+ self.access_counter = counter
51
+
52
+
53
+ class BaseCache:
54
+ """缓存抽象基类"""
55
+
56
+ def __init__(self, max_size: int = 1024, ttl: int = 3600):
57
+ self.max_size = max_size
58
+ self.ttl = ttl
59
+ self._cache: Dict[str, CacheEntry] = {}
60
+ self._lock = __import__('threading').RLock()
61
+ self._access_counter = 0 # 单调递增的访问计数器
62
+
63
+ def _increment_counter(self) -> int:
64
+ """递增访问计数器"""
65
+ self._access_counter += 1
66
+ return self._access_counter
67
+
68
+ def get(self, key: str) -> Optional[Any]:
69
+ """获取缓存"""
70
+ with self._lock:
71
+ if key not in self._cache:
72
+ return None
73
+
74
+ entry = self._cache[key]
75
+
76
+ # 检查过期
77
+ if entry.is_expired():
78
+ del self._cache[key]
79
+ return None
80
+
81
+ # 更新访问信息(使用计数器)
82
+ entry.touch(self._increment_counter())
83
+ return entry.value
84
+
85
+ def put(self, key: str, value: Any) -> None:
86
+ """设置缓存"""
87
+ with self._lock:
88
+ # 最大容量小于等于0时不存储
89
+ if self.max_size <= 0:
90
+ return
91
+
92
+ # 如果键已存在,更新值并标记为最近访问
93
+ if key in self._cache:
94
+ self._cache[key].value = value
95
+ self._cache[key].last_accessed = time.time()
96
+ self._cache[key].access_count += 1
97
+ self._cache[key].access_counter = self._increment_counter()
98
+ return
99
+
100
+ # 检查容量,需要腾出空间
101
+ while len(self._cache) >= self.max_size:
102
+ self._evict()
103
+
104
+ # 创建新条目(使用当前计数器值)
105
+ self._cache[key] = CacheEntry(key, value, self.ttl, self._increment_counter())
106
+
107
+ def delete(self, key: str) -> None:
108
+ """删除缓存"""
109
+ with self._lock:
110
+ if key in self._cache:
111
+ del self._cache[key]
112
+
113
+ def remove(self, key: str) -> None:
114
+ """删除缓存(delete的别名)"""
115
+ self.delete(key)
116
+
117
+ def clear(self) -> None:
118
+ """清空缓存"""
119
+ with self._lock:
120
+ self._cache.clear()
121
+
122
+ def size(self) -> int:
123
+ """获取缓存大小"""
124
+ with self._lock:
125
+ return len(self._cache)
126
+
127
+ @abstractmethod
128
+ def _evict(self) -> None:
129
+ """驱逐策略(由子类实现)"""
130
+ pass
131
+
132
+
133
+ class LRUCache(BaseCache):
134
+ """LRU缓存(最近最少使用)"""
135
+
136
+ def _evict(self) -> None:
137
+ """驱逐最久未使用的缓存(使用计数器判断)"""
138
+ oldest_key = None
139
+ oldest_counter = float('inf')
140
+
141
+ for key, entry in self._cache.items():
142
+ if entry.access_counter < oldest_counter:
143
+ oldest_counter = entry.access_counter
144
+ oldest_key = key
145
+
146
+ if oldest_key:
147
+ del self._cache[oldest_key]
148
+ logger.debug(f"LRU缓存驱逐: {oldest_key}")
149
+
150
+
151
+ class FIFOCache(BaseCache):
152
+ """FIFO缓存(先进先出)"""
153
+
154
+ def _evict(self) -> None:
155
+ """驱逐最早创建的缓存"""
156
+ oldest_key = None
157
+ oldest_time = float('inf')
158
+
159
+ for key, entry in self._cache.items():
160
+ if entry.created_at < oldest_time:
161
+ oldest_time = entry.created_at
162
+ oldest_key = key
163
+
164
+ if oldest_key:
165
+ del self._cache[oldest_key]
166
+ logger.debug(f"FIFO缓存驱逐: {oldest_key}")
167
+
168
+
169
+ class LFUCache(BaseCache):
170
+ """LFU缓存(最不经常使用)"""
171
+
172
+ def _evict(self) -> None:
173
+ """驱逐访问次数最少的缓存"""
174
+ least_key = None
175
+ least_count = float('inf')
176
+
177
+ for key, entry in self._cache.items():
178
+ if entry.access_count < least_count:
179
+ least_count = entry.access_count
180
+ least_key = key
181
+
182
+ if least_key:
183
+ del self._cache[least_key]
184
+ logger.debug(f"LFU缓存驱逐: {least_key}")
185
+
186
+
187
+ class SqlCache:
188
+ """SQL查询缓存"""
189
+
190
+ def __init__(self, cache_type: str = 'lru', max_size: int = 1024, ttl: int = 3600):
191
+ cache_classes = {
192
+ 'lru': LRUCache,
193
+ 'fifo': FIFOCache,
194
+ 'lfu': LFUCache
195
+ }
196
+ self.cache = cache_classes.get(cache_type, LRUCache)(max_size, ttl)
197
+
198
+ def _generate_key(self, sql: str, params: Optional[Dict[str, Any]]) -> str:
199
+ """生成缓存key"""
200
+ key = f"{sql}"
201
+ if params:
202
+ # 对参数进行排序后拼接,确保相同参数生成相同key
203
+ sorted_params = sorted(params.items())
204
+ key += str(sorted_params)
205
+ return hashlib.sha256(key.encode()).hexdigest()
206
+
207
+ def get(self, sql: str, params: Optional[Dict[str, Any]]) -> Optional[Any]:
208
+ """获取SQL查询缓存"""
209
+ key = self._generate_key(sql, params)
210
+ return self.cache.get(key)
211
+
212
+ def put(self, sql: str, params: Optional[Dict[str, Any]], value: Any) -> None:
213
+ """设置SQL查询缓存"""
214
+ key = self._generate_key(sql, params)
215
+ self.cache.put(key, value)
216
+
217
+ def delete(self, sql: str, params: Optional[Dict[str, Any]]) -> None:
218
+ """删除SQL查询缓存"""
219
+ key = self._generate_key(sql, params)
220
+ self.cache.delete(key)
221
+
222
+ def clear(self) -> None:
223
+ """清空缓存"""
224
+ self.cache.clear()
225
+
226
+ def size(self) -> int:
227
+ """获取缓存大小"""
228
+ return self.cache.size()
229
+
230
+
231
+ class ResultMapCache:
232
+ """结果映射缓存"""
233
+
234
+ def __init__(self, max_size: int = 100, ttl: int = 86400):
235
+ self.cache = LRUCache(max_size, ttl)
236
+
237
+ def get(self, key: str) -> Optional[Any]:
238
+ """获取结果映射缓存"""
239
+ return self.cache.get(key)
240
+
241
+ def put(self, key: str, value: Any) -> None:
242
+ """设置结果映射缓存"""
243
+ self.cache.put(key, value)
244
+
245
+ def delete(self, key: str) -> None:
246
+ """删除结果映射缓存"""
247
+ self.cache.delete(key)
248
+
249
+ def clear(self) -> None:
250
+ """清空缓存"""
251
+ self.cache.clear()
252
+
253
+
254
+ class XMLParserCache:
255
+ """XML解析缓存"""
256
+
257
+ def __init__(self, max_size: int = 50, ttl: int = 86400):
258
+ self.cache = LRUCache(max_size, ttl)
259
+ self._parsed_files: Dict[str, float] = {} # 文件路径 -> 解析时间
260
+
261
+ def get(self, file_path: str) -> Optional[Any]:
262
+ """获取XML解析缓存"""
263
+ return self.cache.get(file_path)
264
+
265
+ def put(self, file_path: str, value: Any) -> None:
266
+ """设置XML解析缓存"""
267
+ self.cache.put(file_path, value)
268
+ self._parsed_files[file_path] = time.time()
269
+
270
+ def delete(self, file_path: str) -> None:
271
+ """删除XML解析缓存"""
272
+ self.cache.delete(file_path)
273
+ self._parsed_files.pop(file_path, None)
274
+
275
+ def is_cached(self, file_path: str) -> bool:
276
+ """检查文件是否已缓存"""
277
+ return file_path in self._parsed_files
278
+
279
+ def get_parse_time(self, file_path: str) -> Optional[float]:
280
+ """获取文件解析时间"""
281
+ return self._parsed_files.get(file_path)
282
+
283
+ def clear(self) -> None:
284
+ """清空缓存"""
285
+ self.cache.clear()
286
+ self._parsed_files.clear()
287
+
288
+
289
+ class PrecompiledSqlCache:
290
+ """预编译SQL缓存"""
291
+
292
+ def __init__(self, max_size: int = 500, ttl: int = 3600):
293
+ self.cache = LRUCache(max_size, ttl)
294
+
295
+ def _generate_key(self, sql: str) -> str:
296
+ """生成预编译SQL缓存key"""
297
+ return hashlib.sha256(sql.encode()).hexdigest()
298
+
299
+ def get(self, sql: str) -> Optional[Any]:
300
+ """获取预编译SQL缓存"""
301
+ key = self._generate_key(sql)
302
+ return self.cache.get(key)
303
+
304
+ def put(self, sql: str, prepared_stmt: Any) -> None:
305
+ """设置预编译SQL缓存"""
306
+ key = self._generate_key(sql)
307
+ self.cache.put(key, prepared_stmt)
308
+
309
+ def delete(self, sql: str) -> None:
310
+ """删除预编译SQL缓存"""
311
+ key = self._generate_key(sql)
312
+ self.cache.delete(key)
313
+
314
+ def clear(self) -> None:
315
+ """清空缓存"""
316
+ self.cache.clear()
317
+
318
+
319
+ class SecondLevelCache:
320
+ """二级缓存(跨会话缓存)"""
321
+
322
+ def __init__(self, max_size: int = 1000, ttl: int = 300):
323
+ self.cache = LRUCache(max_size, ttl)
324
+ self._table_cache_map: Dict[str, List[str]] = {} # 表名 -> 缓存key列表
325
+
326
+ def _generate_key(self, table_name: str, params: Dict[str, Any]) -> str:
327
+ """生成缓存key"""
328
+ key = f"{table_name}_"
329
+ if params:
330
+ sorted_params = sorted(params.items())
331
+ key += str(sorted_params)
332
+ return hashlib.sha256(key.encode()).hexdigest()
333
+
334
+ def get(self, table_name: str, params: Dict[str, Any]) -> Optional[Any]:
335
+ """获取二级缓存"""
336
+ key = self._generate_key(table_name, params)
337
+ return self.cache.get(key)
338
+
339
+ def put(self, table_name: str, params: Dict[str, Any], value: Any) -> None:
340
+ """设置二级缓存"""
341
+ key = self._generate_key(table_name, params)
342
+ self.cache.put(key, value)
343
+
344
+ # 记录表名对应的缓存key
345
+ if table_name not in self._table_cache_map:
346
+ self._table_cache_map[table_name] = []
347
+ self._table_cache_map[table_name].append(key)
348
+
349
+ def invalidate_table(self, table_name: str) -> None:
350
+ """使指定表的所有缓存失效"""
351
+ if table_name in self._table_cache_map:
352
+ for key in self._table_cache_map[table_name]:
353
+ self.cache.delete(key)
354
+ del self._table_cache_map[table_name]
355
+ logger.debug(f"二级缓存失效: 表 {table_name}")
356
+
357
+ def invalidate_all(self) -> None:
358
+ """使所有缓存失效"""
359
+ self.cache.clear()
360
+ self._table_cache_map.clear()
361
+
362
+ def clear(self) -> None:
363
+ """清空缓存"""
364
+ self.cache.clear()
365
+ self._table_cache_map.clear()
366
+
367
+
368
+ # 全局缓存实例
369
+ GLOBAL_XML_CACHE = XMLParserCache()
370
+ GLOBAL_PRECOMPILED_CACHE = PrecompiledSqlCache()
371
+ GLOBAL_SECOND_LEVEL_CACHE = SecondLevelCache()