MetaModelService / PageSchemaService
MetaModelService 与 PageSchemaService 是 AuraBoot 元数据目录的 canonical 只读 API —— 涵盖 core 与已安装插件贡献的每一个 model、field 与 page 定义。它们把磁盘上的 JSON 布局、插件 overlay 优先级以及缓存解析都隐藏在一组内存查询方法之后。
概念
在插件 import 时,宿主会从每个插件解析 models.json、pages.json、commands.json、bindingRules.json、permissions.json 等文件,并合并为单一的 tenant 隔离元数据目录。后续对 MetaModelService 的调用都走内存缓存查询。该元数据在运行时 只读;变更通过 import 路径执行,并触发缓存刷新。
要回答"model X 有哪些字段",应该用这些 Service —— 不要自己重新解析 JSON。
接口签名
package com.auraboot.framework.meta.service;
public interface MetaModelService {
Optional<ModelDefinition> getModelDefinition(String modelCode);
FieldDefinition getFieldDefinition(String modelCode, String fieldCode);
List<FieldDefinition> getModelFields(String modelCode); // model 全部字段
/** model 对应的动态表名 —— 例如 "crm_lead" → "mt_crm_lead"。 */
String getTableName(String modelCode);
boolean isModelExists(String modelCode);
boolean isFieldExists(String modelCode, String fieldCode);
void refreshModelCache(String modelCode);
}page 定义由独立的 PageSchemaService 提供:
package com.auraboot.framework.meta.service;
public interface PageSchemaService {
PageSchemaDTO findByPageKey(String pageKey); // 如 "crm_lead-list"
List<PageSchemaDTO> findByModelCode(String modelCode); // list/form/detail 三种 kind
List<PageSchemaDTO> findByKind(String kind);
}ModelDefinition 与 FieldDefinition 都是 Lombok @Data DTO,包含原始配置加便利访问方法(isRequired()、isSearchable()、isDisplayField()、getDefaultValue())。
实现示例
一个自定义报表 Service,从 model 的字段定义动态构造列清单:
package com.acme.report;
import com.auraboot.framework.meta.service.MetaModelService;
import com.auraboot.framework.meta.dto.FieldDefinition;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class ReportColumnService {
@Autowired private MetaModelService metaModelService;
public List<ReportColumn> columnsFor(String modelCode) {
return metaModelService.getModelFields(modelCode).stream()
.filter(FieldDefinition::isSearchable)
.map(f -> new ReportColumn(
f.getCode(),
f.getDisplayName(),
f.getDataType(),
f.isRequired()))
.toList();
}
}一个 page 感知的示例 —— 为列表页解析其动态表:
PageSchemaDTO page = pageSchemaService.findByPageKey("crm_lead-list");
String table = metaModelService.getTableName(page.getModelCode()); // "mt_crm_lead"注册
MetaModelService 与 PageSchemaService 都是宿主托管的 Spring bean。在任意插件扩展或平台 Service 中通过 @Autowired 注入即可。这里没有 SPI 可供实现 —— 它们是 Service,而不是扩展点。元数据缓存在插件 enable/disable 以及 model.published 事件触发时自动刷新。
常见陷阱
- 调用
getTableName(modelCode)时假设结果是ab_dyn_<code>。 真实前缀是mt_<modelCode>(常量SystemFieldConstants.DYNAMIC_TABLE_PREFIX,见红线 §15)。始终调用 API。 - 跨插件 reload 缓存
ModelDefinition/FieldDefinition引用。 缓存刷新会产生新实例;旧引用是陈旧的。请缓存 code 并按需查询。 - 直接读取 JSON 文件。 会绕过 overlay 优先级与校验。始终走 Service。
- 假设
findByPageKey(modelCode + "-list")返回的是用户自定义页面。MetaModelServiceImpl.autoCreateDefaultPages在 model publish 时会静默生成空 stub —— 把它当成真实页面前应检查其 blocks 是否为空。