11---
22name : egg-core
3- description : 本技能用于处理 EGG 基础核心概念,包括模块架构、@SingletonProto、@ContextProto、@Inject 装饰器和动态注入 。用于理解 EGG 的基础构建块、依赖注入、对象生命周期管理和运行时多实现动态选择 。
3+ description : 本技能用于处理 EGG 基础核心概念,包括模块架构、@SingletonProto、@ContextProto、@Inject 装饰器、动态注入、BackgroundTaskHelper 后台任务、EventBus 事件总线和 AOP 切面编程 。用于理解 EGG 的基础构建块、依赖注入、对象生命周期管理、运行时多实现动态选择、请求返回后的异步任务处理、事件驱动架构和横切关注点 。
44allowed-tools : Read
55---
66
77# egg 核心概念
88
9- ## Step 1: 代码写在 module 中
9+ ## 代码组织与依赖注入
1010
11- ### 什么是模块?
11+ ### Step 1: 代码写在 module 中
12+
13+ #### 什么是模块?
1214
1315模块是 EGG 中基础的代码组织单元。只有模块内的代码会被框架扫描和加载。模块之间相互独立,但可以通过 ` @Inject ` 装饰器访问其他模块的对象。
1416
15- ### 定义 module
17+ #### 定义 module
1618
1719在目录中添加包含 ` eggModule.name ` 字段的 ` package.json ` 文件来声明该目录为模块:
1820
@@ -97,9 +99,9 @@ import { SingletonProto } from '@eggjs/tegg';
9799
98100---
99101
100- ## Step 2: 用 Proto 实现 Service
102+ ### Step 2: 用 Proto 实现 Service
101103
102- ### SingletonProto
104+ #### SingletonProto
103105
104106应用启动时立即创建,整个应用生命周期内只有一个实例,性能更好,应该作为默认选择。
105107
@@ -114,7 +116,7 @@ export class HelloService {
114116}
115117```
116118
117- ### ContextProto
119+ #### ContextProto
118120
119121请求到达时按需创建,每个请求一个实例,请求结束自动销毁。仅在需要隔离不同请求的上下文信息时使用。
120122
@@ -129,7 +131,7 @@ export class RequestContext {
129131
130132** 重要提示** :大多数服务应该使用 ` SingletonProto ` 以获得更好的性能。只有当请求上下文必须在服务之间共享以确保请求之间隔离时,才使用 ` ContextProto ` 。
131133
132- ### AccessLevel
134+ #### AccessLevel
133135
134136proto 对象默认 accessLevel 为 ` AccessLevel.PRIVATE ` ,仅在当前 module 内使用。可以设置为 ` AccessLevel.PUBLIC ` ,进行跨模块访问。
135137
@@ -143,9 +145,9 @@ export class SharedService {}
143145export class SharedContextService {}
144146```
145147
146- ## Step 3: 通过 Inject 使用 Service
148+ ### Step 3: 通过 Inject 使用 Service
147149
148- ### 基本用法
150+ #### 基本用法
149151
150152使用 ` @Inject() ` 注入其他 Proto 或 Egg 对象:
151153
@@ -167,43 +169,62 @@ export class HelloService {
167169}
168170```
169171
170- ### 动态注入
172+ #### 动态注入
171173
172174当同一个抽象有多种实现,需要在运行时动态选择时,通过 ` EggObjectFactory ` 按类型获取实现,无需 if/else。详见 ` references/dynamic-inject.md ` 。
173175
174- ### 重要约束
176+ #### 重要约束
175177
176178- ** 不能有循环依赖** :Proto 或模块之间都不能有循环依赖
177179- ** 不能有同名对象** :一个模块不能有相同名称和初始化类型的 Proto
178180- ** 按需注入** :不要直接注入 ` app ` 或 ` ctx ` ,按需注入特定对象
179181
180- ## 快速决策指南
182+ ### 快速决策指南
183+
184+ | 场景 | 使用方式 |
185+ | -------------------------------- | ------------------------------------------------------ |
186+ | 无状态服务 | ` @SingletonProto() ` |
187+ | 跨服务共享的请求级状态 | ` @ContextProto() ` |
188+ | 需要跨模块访问 | ` @SingletonProto({ accessLevel: AccessLevel.PUBLIC }) ` |
189+ | 注入依赖 | ` @Inject() ` |
190+ | 使用自定义名称注入 | ` @Inject({ name: 'customName' }) ` |
191+ | 同一抽象多种实现,运行时动态选择 | ` QualifierImplDecoratorUtil ` + ` EggObjectFactory ` |
181192
182- | 场景 | 使用装饰器 |
183- | -------------------------------- | ------------------------------------------------------------------ |
184- | 无状态服务 | ` @SingletonProto() ` |
185- | 跨服务共享的请求级状态 | ` @ContextProto() ` |
186- | 需要跨模块访问 | ` @SingletonProto({ accessLevel: AccessLevel.PUBLIC }) ` |
187- | 注入依赖 | ` @Inject() ` |
188- | 使用自定义名称注入 | ` @Inject({ name: 'customName' }) ` |
189- | 同一抽象多种实现,运行时动态选择 | ` QualifierImplDecoratorUtil ` + ` EggObjectFactory ` |
190- | 请求返回后执行异步任务 | ` BackgroundTaskHelper.run() ` ,详见 ` references/background-task.md ` |
193+ ## 异步任务
191194
192- ### 异步任务选型
195+ | 特性 | BackgroundTaskHelper | EventBus |
196+ | ---------- | ----------------------------- | ----------------------------------------- |
197+ | ** 耦合** | 高 — 异步逻辑写在触发者代码中 | 低 — handler 独立,新增处理者不修改触发者 |
198+ | ** 上下文** | 共享触发者的请求上下文 | handler 运行在独立的新上下文中 |
199+ | ** 扩展** | 需要修改触发者代码 | 新增 ` @Event ` handler 类即可 |
193200
194201```
195202需要在请求之外执行任务?
196203│
197204├─ 请求返回后执行,依赖当前请求上下文
198205│ └─ → BackgroundTaskHelper(references/background-task.md)
199206│
200- ├─ 请求返回后执行,不依赖当前请求上下文
201- │ └─ → EventBus
207+ ├─ 请求返回后执行,不依赖当前请求上下文,需要解耦
208+ │ └─ → EventBus(references/eventbus.md)
202209│
203210└─ 定时或周期执行
204211 └─ → Schedule(参考 egg-controller skill)
205212```
206213
214+ ## AOP 切面编程
215+
216+ AOP 用于将日志、鉴权、缓存、事务等横切关注点从业务代码中分离。AOP 装饰器从 ` egg/aop ` 导入(不是 ` egg ` )。
217+
218+ ```
219+ 需要在方法执行前后添加通用逻辑?
220+ │
221+ ├─ 针对特定方法 → @Pointcut(在目标方法上声明)
222+ │
223+ └─ 批量切入多个类/方法 → @Crosscut(在 Advice 类上声明匹配规则)
224+ ```
225+
226+ 详细用法(Advice 生命周期、AdviceContext、Pointcut/Crosscut 选型、参数透传、执行顺序)请参阅 ` references/aop.md ` 。
227+
207228## 常见问题排查
208229
209230| 现象 | 原因 | 解决方案 |
@@ -221,3 +242,5 @@ export class HelloService {
221242- SingletonProto 和 ContextProto 详情,请参阅:` references/proto.md `
222243- 动态注入(Qualifier 动态注入),请参阅:` references/dynamic-inject.md `
223244- 请求后异步任务(BackgroundTaskHelper),请参阅:` references/background-task.md `
245+ - 事件总线(EventBus),请参阅:` references/eventbus.md `
246+ - AOP 切面编程(Advice、Pointcut、Crosscut),请参阅:` references/aop.md `
0 commit comments