Skip to content

Spire 总览

Spire(天擎)是一个基于仓颉语言开发、借鉴 ASP.NET Core 设计哲学的现代化 Web 框架。与仓颉官方团队共同研发,致力于打造轻量级、高性能、可扩展的应用开发体验。

适用场景

  • 初次接触 Spire,需要建立四层架构的整体心智模型
  • 需要知道各层之间的依赖关系和阅读顺序
  • 需要理解框架的设计原则和统一的开发公式

核心问题

Spire 不是一堆模块的集合,而是按四层架构组织的能力体系。核心问题是:

  1. 每一层解决什么问题 — 基础设施层提供底座能力、宿主层管理应用生命周期、安全层贯穿认证授权、Web 层处理 HTTP 请求
  2. 层与层之间如何协作 — 上层依赖下层,下层不感知上层;安全层横向贯穿宿主和 Web 两层
  3. 开发者如何统一接入 — 所有能力收敛到 services.addXxx() + host.useXxx() 的注册与使用分离模型

架构全景


四层架构

Spire 采用经典的分层设计。每一层只依赖它下面的一层,上层不知道下层的实现细节。

text
你的应用(Controllers / MiniAPI / 业务逻辑)


Web 层(MVC · MiniAPI · 静态文件 · CORS · OpenAPI · 健康检查)


安全与身份(认证 · 授权 · JWT · 认证中心)


宿主层(通用主机 · Web 主机 · 中间件管道)


基础设施层(DI · 配置 · 选项 · 日志 · HTTP · 缓存 · 序列化 · 对象池 · Mediator)


仓颉运行时

基础设施层

框架的底座。 九项基础设施各自解决一类通用工程问题——依赖注入组装对象、配置系统管理设置、日志记录运行时信息、HttpClient 发请求、缓存加速读取、序列化转换数据、对象池复用资源、Mediator 收敛横切逻辑。每一项都是一行 services.addXxx() 注册,DI 容器统一管理生命周期和依赖关系。

完整说明见 基础设施总览

宿主层

应用的骨骼。 通用主机提供统一的启动/停止生命周期、环境管理、配置加载;Web 主机在通用主机之上增加 HTTP 监听和中间件管道。中间件管道是请求处理的核心模型——每个请求依次经过一串中间件,每个中间件在 next() 前后都有执行机会。

完整说明见 通用主机 · Web 主机

安全与身份

贯穿多层的横切面。 认证(Authentication)负责"你是谁"——从 JWT 或 Cookie 中解析用户身份,挂到 context.user;授权(Authorization)负责"你能干什么"——根据 endpoint 上的权限标注校验当前用户是否有权访问。认证中心(Identity Server)提供完整的 OAuth 2.0 / OpenID Connect 令牌颁发能力。

完整说明见 安全总览 · 认证中心总览

Web 层

面向 HTTP 的能力集合。 MVC 提供结构化控制器开发;MiniAPI 提供极简端点注册;静态文件托管 SPA 构建产物;CORS 处理跨域请求;OpenAPI 自动生成 API 文档;健康检查暴露探活端点。所有 Web 能力都通过中间件注册到管道中。

完整说明见 Web 总览


能力矩阵

Spire 的能力分布在四层中,每一项解决一类开发中的常见问题。

层级模块一句话概括核心接口/入口
基础设施依赖注入统一组装对象,管理生命周期services.addXxx()
基础设施配置系统多源叠加,统一读取config["section:key"]
基础设施选项模式强类型配置,启动期校验IOptions<T>
基础设施日志系统记录与输出解耦ILogger
基础设施HttpClient请求管道与生命周期管理IHttpClientFactory
基础设施分布式缓存统一缓存接口,切换后端不改代码IDistributedCache
基础设施序列化编译期宏生成,字段改一处@Serialization
基础设施对象池高频对象复用,降低 GC 压力ObjectPool<T>.get()/put()
基础设施Mediator请求与处理器解耦,横切逻辑收敛IMediator.send()
宿主通用主机启动/停止、环境、配置、DIHost.createBuilder()
宿主Web 主机HTTP 监听、中间件管道WebHost.createBuilder()
安全认证验 token,解析用户身份useAuthentication()
安全授权验权限,放行或拦截useAuthorization()
安全JWT 令牌颁发和验证 JWTJwtSecurityTokenHandler
安全认证中心OAuth 2.0 / OIDC 令牌服务IdentityServer
WebMVC结构化控制器开发@Route["..."] + mapControllers()
WebMiniAPI极简端点注册app.mapGet("/hello") { => ... }
Web静态文件SPA 构建产物托管useFileServer()
WebCORS跨域预检与响应头处理useCors("策略名")
WebOpenAPI自动生成 API 文档mapOpenApi() + useOpenApiUI()
Web健康检查暴露探活端点useHealthChecks("/health")

框架设计原则

Spire 的架构不是凭空设计的,它遵循四条原则。理解这四条原则,你就理解了几十个模块为什么是这种组织方式。

原则一:注册与使用分离

cangjie
// 注册阶段(应用启动时):往 DI 容器里放东西
builder.services.addAuthentication().addJwtBearer { ... }
builder.services.addCors { ... }

// 使用阶段(请求处理时):从 DI 容器取东西,搭管道
host.useAuthentication()
host.useCors("default")

add*use* 不是随便选的命名——add* 往容器里放服务,use* 把服务插入请求处理管道。启动时集中注册,运行时按需取用。

原则二:中间件洋葱模型

每个请求穿过一串中间件,形成层层包裹的"洋葱":

text
        ┌──────────────────────────┐
        │  ExceptionHandler        │  ← 最外层 try-catch
        │  ┌────────────────────┐  │
        │  │  Auth              │  │  ← 验 token
        │  │  ┌──────────────┐  │  │
        │  │  │  Controller  │  │  │  ← 业务逻辑
        │  │  └──────────────┘  │  │
        │  └────────────────────┘  │
        └──────────────────────────┘

每层在 next() 调用前后都有执行机会。认证先解析用户,业务执行完日志再记录耗时——这些横切逻辑不需要 Controller 关心。

原则三:接口隔离,实现可替换

cangjie
// 业务代码依赖接口,不依赖具体实现
class BlogService {
    public init(cache: IDistributedCache) {}     // 不是 MemoryDistributedCache
    public init(http: IHttpClientFactory) {}     // 不是 SocketsHttpHandler
    public init(logger: ILogger) {}               // 不是 ConsoleLogger
}

// 下面换什么实现,上面零改动
appsettings.json "Cache:Provider": "Redis"全系统切换 Redis
services.addHttpMessageHandler<RetryHandler>()  → 加一个重试不碰业务代码

原则四:约定优于配置

能按命名规则自动匹配的,不写配置文件;能从一个注解推导的,不手写三行。

cangjie
// 约定:声明 Request 类型 → Mediator 通过接口自动找到对应 Handler
@Serialization[superType: BlogPost]
public class CreateBlogPostCommand <: IRequest<Unit> {}
// ↑ 只需声明字段;Handler 通过实现 IRequestHandler<CreateBlogPostCommand, Unit> 接口被扫描注册

public class CreateBlogPostCommandHandler <: IRequestHandler<CreateBlogPostCommand, Unit> {
    public func handle(request: CreateBlogPostCommand): Unit { ... }
}
// ↑ MediatorBuilder.registerServices() 扫描包中实现了 IRequestHandler 接口的类型并注册到 DI
//   Mediator.send() 从 DI 按 IRequestHandler<TRequest, TResponse> 泛型接口解析,不依赖类名约定

// 约定:@Route 注解 → 路由表一行代码扫描全部控制器
@Route["api/[controller]/[action]"]
public class BlogController <: Controller { ... }
// ↑ [controller] = Blog, [action] = getList → /api/Blog/getList

无论你在 Spire 的哪一层写代码,都遵循同一条公式:

text
1. 定义接口/类(IOptions<T> / ILogger / DelegatingHandler / Controller / IRequestHandler)

2. 实现接口/继承基类(写业务逻辑)                       ← 你主要做这一步

3. 一行注册到容器(services.addXxx() / host.useXxx())

4. Spire 接管生命周期和依赖解析                        ← 框架帮你做这些

这也是为什么 博客实战项目 虽然有多组控制器、多层架构、复杂的 CQRS 管线,但每个新 Controller 加进来只需要三步:继承基类 → 打注解 → 注册模块。


当前边界

  • 已覆盖:四层架构(基础设施、宿主、安全与身份、Web)的全部模块、框架设计原则、统一开发公式、能力矩阵速查
  • 未覆盖:各模块的详细 API 文档、高级配置项、第三方生态的具体实现

生态共建

Spire 每一层的核心接口都为扩展预留了设计空间——不是"先有内部实现再对外开放",而是每层都先定接口,内部实现和第三方扩展站在同一条起跑线上

层级核心接口可扩展方向
基础设施IDistributedCacheRedis / MongoDB / Memcached 实现
基础设施ILoggerProvider文件 / ES / Kafka / 飞书实现
基础设施ConfigurationProviderNacos / Apollo / Consul 实现
基础设施DelegatingHandler链路追踪 / 熔断 / 签名实现
基础设施IPipelineHandler日志 / 事务 / 校验 / 缓存行为实现
基础设施IPooledObjectPolicy<T>特定类型的资源复用策略
安全AuthenticationSchemeOAuth / SAML / LDAP 方案实现
WebIMiddleware自定义中间件
WebJsonConverter<T>自定义类型序列化

如果你正在为仓颉生态编写类库,请尽量基于 Spire 的接口和选项模式来设计。用户只需一行 services.addXxx(),剩下的由 Spire 接管生命周期、配置绑定和依赖解析。

推荐阅读顺序

顺序文档你学到什么
1快速开始5 分钟跑起来
2基础设施总览理解底座:DI、配置、日志、缓存怎么配合
3通用主机应用怎么启动、怎么配置环境、怎么优雅关闭
4Web 总览HTTP 请求怎么被处理:中间件管道、路由、MVC
5安全总览认证授权怎么打通:JWT、Claim、Token
6Blog 实战把这些能力拼成一个完整的项目

读完之后,你开新项目时就知道:基础设施放哪、控制器怎么写、认证怎么接、整个项目怎么组织。


相关专题