实体聚合根
在使用 Phoenix 框架开发项目时,通常需要借助领域驱动设计(DDD),提取领域实体,其中一个特殊的实体为聚合根(领域外对领域内其他实体的访问都需要通过该聚合根),而Phoenix中的实体聚合根概念就对应DDD中的聚合根。
实体聚合根利用 EventSouring
思想把状态直接存在对象当中,参考Event Souring。在Phoenix当中,单个实体聚合根(同一个聚合根ID)处理请求是单线程的,所以不用担心线程安全问题。当然,如果你希望你的应用是可以横向扩容的,就需要设计好聚合根。
maven依赖
<dependency>
<groupId>com.iquantex</groupId>
<artifactId>phoenix-server-starter</artifactId>
<version>2.4.2</version>
</dependency>
实体聚合根
实体聚合根需要使用@EntityAggregateAnnotation
来标记类,服务启动后phoenix会校验定义规范和创建实体聚合根类对象。实体聚合根类需要遵循如下规范:
- 聚合根类需要使用
@EntityAggregateAnnotation
注解进行标记。 - 聚合根类以及聚合根类中的实体均需实现
Serializable
接口,并定义serialVersionUID。 - 聚合根类需要提供无参构造函数。
注意:在聚合根上添加
@EntityAggregateAnnotation
注解时,需要通过aggregateRootType
指定一个聚合根的类别。用来区分不同的聚合根类,该聚合根类别是全局唯一的。且聚合根ID的长度要小于64个字符。
示例代码
@EntityAggregateAnnotation(aggregateRootType = "BankAccount", idempotentSize = 100, bloomSize = 1000000, snapshotInterval = 100000)
public class BankAccountAggregate implements Serializable {
private static final long serialVersionUID = 6073238164083701075L;
// ... act and on method
}
参数配置
配置项 | 描述 | 类型 | 默认值 |
---|---|---|---|
aggregateRootType | 聚合根类型 | String | 必填项 |
surviveTime | 聚合根生存时间,超过该时间聚合根将被从JVM中淘汰,下一次使用时再重建,减少内存使用 | long | Long.MAX_VALUE |
snapshotInterval | 快照间隔,每隔snapshotInterval条消息打印一次快照,加速聚合根重建,0为关闭 | long | 1000 |
idempotentSize | 聚合根幂等集合大小,取值应大于零,否则可能会导致启动失败 | long | 1000 |
bloomSize | 布隆过滤器大小,内存中识别幂等,减少读库判断 | long | 100000L |
dispatcher | 选择聚合根的调度者,缓解阻塞问题,支持自定义线程池 | String | "phoenix-dispatcher" |
命令处理
实体聚合根中需要提供 act() 方法,用来处理Command消息。一般会产生该领域将会发生的Event事件,通过Event事件修改聚合根状态,也可以直接修改(使用CommandSouring模式)。
对于Command命令和Event事件,Phoenix支持三种协议,详情请参见序列化
。
- protobuf
- protostuff
- java serializable
实体聚合根 中的 act() 方法上需要添加 @CommandHandler
注解进行标识。
示例代码
@CommandHandler(aggregateRootId = "accountCode", isCommandSourcing = true)
public ActReturn act(AccountCreateCmd createCmd) {
this.account = createCmd.getAccountCode();
this.balanceAmt = createCmd.getBalanceAmt();
String message = String.format("初始化账户代码<%s>, 初始化余额<%s>. ", createCmd.getAccountCode(),createCmd.getBalanceAmt());
return ActReturn.builder().retCode(RetCode.SUCCESS).retMessage(message)
.event(new AccountCreateEvent(createCmd.getAccountCode(), createCmd.getBalanceAmt())).build();
}
参数配置
配置项 | 描述 | 类型 | 默认值 |
---|---|---|---|
AggregateRootId | 聚合根id,允许多字段组成并且成员嵌套字段访问aggregateRootId = {event.accountCode, event.name} | String[] | 必填项 |
enableCreateAggregate | 是否允许自动创建聚合根 | boolean | true |
idempotentIds | 幂等id(参考幂等操作 段落详解) | String[] | 采用phoenix默认的幂等id |
isCommandSourcing | 是否是command sourcing,默认是event sourcing | boolean | false |
关于支持多聚合根Id并且嵌套的使用方式
class CommandA {
String name;
CommandB commandb;
}
class CommandB {
String age;
}
@CommandHandler(aggregateRootId = {name, commandb.age})
public ActReturn act(A cmd) {
}