本文介绍工程的脚手架结构、依赖关系和相关Annotation注解。
工程脚手架结构
工程脚手架结构示例如下:
工程Module
Module | 职责 | 说明 |
---|---|---|
Entry | 核心业务入口。 | 业务入口,当应用通过SpringCloud实现则Controller在该模块编写,通过Controller调用底层业务逻辑形成闭环。 |
App | 业务调用入口。 | Entry通过调用App层实现业务逻辑调用。App层需要负责调用Domain层业务逻辑,且将DTO与Domain Entity进行转换。 |
Domain | 领域实现层:核心业务逻辑。 | Domain层主要编写业务逻辑,业务通过建模后,业务逻辑通过Domain Entity和Domain Service来承载,因此是充血模型的方式来完成代码开发。
当涉及对外调用时,则通过调用Domain层定义的Repository Interface来完成,而具体外部访问的技术实现由Infrastructure实现。 |
Infrastructure | 基础设施层:负责技术实现,包括访问DB、Cache、RPC、MQ等。 | Domain会实现业务逻辑,而业务逻辑中涉及到技术实现的部分(例如:保存、RPC请求、MQ发送消息、缓存等)都通过Infrastructure在Repository
Impl实现。
Infrastructure除了技术实现,还包括DO定义、DO与Domain Entity的互相转换,以及集成并调用外部服务的Client。 |
Starter | 应用启动。 | 独立应用启动的包,方便启动方式插拔变更。 |
Client | 商业能力、域服务接口定义。 | 外部应用集成的SDK,便于能力调用。在SDK中定义包括:商业能力、域服务接口定义、接口入参和返回值DTO、接口返回错误码定义、业务自定义异常定义等。 |
Extension | 负责扩展点接口定义。 | 外部应用集成SDK,便于根据扩展点定义实现自定义扩展点业务逻辑。 |
Module依赖关系
Module之间的依赖关系详情如下图所示:
Module请求流向
Module请求流向详情如下图所示:
工程Annotation注解
BizWorks规范注解
注解 | 含义 | 常用属性 | 说明 |
---|---|---|---|
@ApplicationService | 应用服务注解 |
|
加在接口上,声明该接口属于应用服务。 |
@DomainService | 领域服务注解 |
|
加在类上,声明该类属于领域服务。 |
@DomainObject | 领域对象注解 |
|
加在类上,声明该类属于领域对象。 |
@ValueObject | 值对象注解 |
|
加在类上,声明该类属于值对象。 |
@StructureObject | 结构对象注解 |
|
加在类上,声明该类属于结构对象。 |
@ExtensionPoint | 扩展点注解 |
|
加在方法上,声明该方法属于扩展点。 |
@Field | 属性注解 |
|
加在属性上。 |
@Method | 方法注解 |
|
加在方法上。 |
@Related | 扩展点注解 | to :扩展点指向的类
|
加在方法上,扩展点不独立存在,扩展点依附于应用服务。 |
@Parameter | 参数注解 |
|
加在方法入参上。 |
@ReturnValue | 返回值注解 |
|
当方法有返回值时加在方法上。 |
添加POM依赖
添加POM依赖示例如下:
<dependency>
<groupId>com.alibaba.bizworks</groupId>
<artifactId>core-specification</artifactId>
<version>${bizworks-app-framework.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba.bizworks</groupId>
<artifactId>core-runtime-container</artifactId>
<version>${bizworks-app-framework.version}</version>
</dependency>
Annotation注解示例
- 应用服务@ApplicationService
@PostMapping("/DemoAppService") @ApplicationService(domain = "DemoDomain" , name = "示例应用服务", desc = "示例应用服务描述") public interface DemoAppService { @ReturnValue(value = "SingleResponse结构验证", name = "SingleResponse结构验证") @Method(value = "创建用户", name = "创建用户") @PostMapping(value = "/createUser") SingleResponse createUser(@Parameter(value = "参数描述信息", name = "参数名", required = true) @Valid @RequestBody UserDTO userDTO); } }
此示例中包含了@ApplicationService、@ReturnValue、@Method、@Parameter注解的使用样例。说明 @ApplicationService注解中domain
的属性值必须是建立的业务域的编码。本文中domain
属性值的来源都必须遵循这个规则,同一个业务域domain
属性值必须相同。 - 应用服务的结构对象@StructureObject
应用服务的出入参数若为Java对象,则该Java对象通常都应被标注为结构对象。
@Getter @Setter @StructureObject(name = "用户对象DTO", desc = "用户对象DTO") public class UserDTO { @Field(value = "用户名", name = "用户名") private String username; @Field(value = "邮箱", name = "邮箱") private String email; }
此示例中包含了@StructureObject、@Field注解的使用样例。说明 @StructureObject中asset
的属性值必须是建立的业务域的编码,且assetType = "MODULE_CENTER"
。 - 领域对象@DomainObject(实体对象)及@ValueObject(值对象)
@Data @DomainObject(domain = "DemoDomain", isAggregateRoot = true, name = "用户", desc = "用户") public class User extends BaseEntity { @Field(value = "用户名", name = "用户名") private String username; @Field(value = "邮箱", name = "邮箱") private String email; }
@ValueObject(domain = "DemoDomain", name = "地址", desc = "地址") public class Address { @Field(value = "区域", name = "区域") private String region; @Field(value = "详细地址", name = "详细地址") private String detail; }
此示例中包含了@DomainObject ,@ValueObject, @Field注解的使用样例。
- 领域服务@DomainService
@DomainService(domain = "DemoDomain", name = "示例领域服务", desc = "示例领域服务描述") public class DemoDomainService { @ReturnValue(value = "返回值描述", name = "返回值名称") @Method(value = "关联用户地址", name = "关联用户地址") public SingleResponse bind(User user, Address address) { // 调用领域对象1.方法() // 调用领域对象2.方法() return SingleResponse.buildSuccess(); } }
此示例中包含了@DomainService,@ReturnValue,@Method,@Parameter注解的使用样例。
- 商业能力@BusinessCapabilityService
@PostMapping("/DemoBizCapService") @BusinessCapabilityService(businessCapability = "DemoBizCap", desc = "示例商业能力服务描述 desc", name = "示例商业能力服务") public interface DemoBizCapService { @ReturnValue(value = "SingleResponse结构验证", name = "SingleResponse结构验证") @Method(value = "验证并激活用户", name = "验证并激活用户") @PostMapping(value = "/verifyAndActive") SingleResponse verifyAndActive(@Parameter(value = "参数描述信息", name = "参数名", required = true) @RequestBody UserInfoDTO userInfoDTO); }
此示例中包含了@BusinessCapabilityService,@ReturnValue,@Method,@Parameter注解的使用样例。说明 @BusinessCapabilityService 注解中businessCapability
的属性值必须是建立的商业能力的编码,本文中businessCapability
属性值的来源都必须遵循这个规则,同一个商业能力的businessCapability
属性值必须相同。 - 商业能力的结构对象@StructureObject
商业能力服务的方法出入参数若为Java对象,该Java对象通常都应被标注为结构对象。商业能力的结构对象应用服务的结构对象没有区别,示例:略。
用配置文件替代注解
采用以上注解的添加方式其实已经可以实现业务域、商业能力的扫描上报。但是如果不希望在代码注解里标注业务域或商业能力的编码或类型,您可以采用配置文件的方式来描述这部分信息。在如下图所示位置(启动Module的resources/bizworks路径下),添加modules.yaml文件。
modules.yaml文件样例如下:
---
bizworks:
modules:
- type: "MODULE_CENTER"
code: "ExtendsDoamin"
packages:
- "com.alibaba.bizworks.testapp11.businessdomain.extendsdoamin"
- type: "BUSINESS_CAPABILITY"
code: "BindBiz03"
packages:
- "com.alibaba.bizworks.testapp11.businesscapability.bindbiz03"
关于modules.yaml属性的含义,请参见下表:
参数 | 含义 | 说明 |
---|---|---|
type | 类型 | 业务域:MODULE_CENTER 商业能力:BUSINESS_CAPABILITY。 |
code | 编码 | 业务域或商业能力的编码。 |
packages | 包路径 | 代码扫描的包路径。 |
配置BWAF日志组件
BWAF框架日志打印需要添加如下依赖:
<dependency>
<groupId>com.alibaba.bizworks</groupId>
<artifactId>logging</artifactId>
<version>${bizworks-app-framework.version}</version>
</dependency>
添加依赖后,重启服务,发起请求,即可查看到BWAF相关日志输出。
配置本地调试BWAF参数
在本地调试的时候,为了您的项目可以正常运行,需要添加以下配置。
bizworks:
#此处配置为该工程的applicationCode。
appId: myAppId # 应用ID(仅本地运行时需要配置,平台部署时由平台注入环境变量)。
bizId: myBizId # 业务身份 (中心应用一般不需要配置该项)。
appVersion: 1.0.6 # 应用版本(仅本地运行时需要配置,平台部署时由平台注入环境变量)。
tenantId: myTenantId # 租户ID(仅本地运行时需要配置,平台部署时由平台注入环境变量)。
envId: myProject.myEnv # 环境ID ${项目ID}.{环境ID}(仅本地运行时需要配置,平台部署时由平台注入环境变量)。
endpoint: bw.app.bizworks.cn # 应用本身的Endpoint(仅本地运行时需要配置,平台部署时由平台注入环境变量)。
extensionPointRegistryServer: bizworks-registry.bizworks.svc.cluster.local # 扩展点注册中心地址。
projectId: national-tobacco-project # 当前项目ID(仅本地运行时需要配置,平台部署时由平台注入环境变量)。