1. bean组件名称:beanFullName
每一个注册的Bean组件都被分配了全称,具体规则如下
注册名称 | 场景 | 所属模块 | global | beanFullName |
---|---|---|---|---|
test.app | test | test-party | false | test-party.test.app |
testctx | test-party | true | testctx |
全局Bean(
global:true
): 当一个Bean组件可以作为一个核心的基础组件的时候,可以设置为全局Bean,方便其他模块的调用,比如:atom
、user
、role
、flow
、flowTask
,等等
本地Bean(
global:false
): 当一个Bean组件一般只用于本模块时,可以设置为本地Bean,从而避免命名冲突
场景:对于
本地Bean
,我们一般为其分配一个场景名称
作为前缀,一方面便于Bean的分类管理,另一方面也便于辨识Bean的用途
2. 基本调用:ctx.bean
可以直接通过this.ctx.bean
取得Bean容器,然后通过beanFullName
获取Bean实例
src/suite-vendor/test-party/modules/test-party/backend/src/controller/test/feat/bean.js
- 1
- 2 // global: false
- 3 this.ctx.bean['test-party.test.app'].actionSync({ a, b });
- 4 await this.ctx.bean['test-party.test.app'].actionAsync({ a, b });
- 5
- 6 // global: true
- 7 this.ctx.bean.testctx.actionSync({ a, b });
- 8 await this.ctx.bean.testctx.actionAsync({ a, b });
3. 新建Bean实例:ctx.bean._newBean
通过this.ctx.bean
获取Bean实例,那么这个实例对当前ctx
而言是单例的。如果需要新建Bean实例,可以按如下方式进行:
- 1ctx.bean._newBean(beanFullName, ...args)
比如我们要新建一个Flow实例:
src/module-system/a-flow/backend/src/bean/bean.flow.js
- 1 _createFlowInstance({ flowDef }) {
- 2 const flowInstance = ctx.bean._newBean(`${moduleInfo.relativeName}.local.flow.flow`, {
- 3 flowDef,
- 4 });
- 5 return flowInstance;
- 6 }
4. 跨模块调用本地Bean:ctx.executeBean
本地Bean也可以被跨模块调用
跨模块调用的本质:新建一个ctx上下文环境,该ctx的module信息与本地Bean一致,然后通过新容器
ctx.bean
来调用本地Bean
- 1await ctx.executeBean({ locale, subdomain, beanModule, beanFullName, context, fn, transaction })
名称 | 可选 | 说明 |
---|---|---|
locale | 可选 | 默认等于ctx.locale |
subdomain | 可选 | 默认等于ctx.subdomain |
beanModule | 必需 | 本地Bean所属模块名称 |
beanFullName | 必需 | 本地Bean的全称 |
context | 可选 | 调用本地Bean时传入的参数 |
fn | 必需 | 调用本地Bean的方法名 |
transaction | 可选 | 是否要启用数据库事务 |
比如我们要调用模块a-file
的本地Bean: service.file
,直接上传用户的avatar,并返回downloadUrl
src/module-system/a-base-sync/backend/src/bean/bean.user.js
- 1 // upload
- 2 const res2 = await ctx.executeBean({
- 3 beanModule: 'a-file',
- 4 beanFullName: 'a-file.service.file',
- 5 context: { fileContent: res.data, meta, user: null },
- 6 fn: '_upload',
- 7 });
- 8 // hold
- 9 profile._avatar = res2.downloadUrl;
5. 全局Bean容器:app.bean
ctx.bean
是每个请求初始化一个容器,而app.bean
则可以实现整个应用使用一个容器,从而实现Bean组件的应用级别的单例模式
src/suite-vendor/test-party/modules/test-party/backend/src/controller/test/feat/bean.js
- 1 app.bean['test-party.test.app'].actionSync({ a, b });
- 2 await app.bean['test-party.test.app'].actionAsync({ a, b });
评论: