Maven依赖
pom.xml
<properties> <cola.components.version>5.0.0</cola.components.version> </properties> <!-- 版本管理 --> <dependencyManagement> <dependencies> <dependency> <groupId>com.alibaba.cola</groupId> <artifactId>cola-components-bom</artifactId> <version>${cola.components.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <!-- 组件 --> <dependencies> <dependency> <groupId>com.alibaba.cola</groupId> <artifactId>cola-component-dto</artifactId> </dependency> <dependency> <groupId>com.alibaba.cola</groupId> <artifactId>cola-component-exception</artifactId> </dependency> <dependency> <groupId>com.alibaba.cola</groupId> <artifactId>cola-component-catchlog-starter</artifactId> </dependency> <dependency> <groupId>com.alibaba.cola</groupId> <artifactId>cola-component-domain-starter</artifactId> </dependency> <dependency> <groupId>com.alibaba.cola</groupId> <artifactId>cola-component-extension-starter</artifactId> </dependency> <dependency> <groupId>com.alibaba.cola</groupId> <artifactId>cola-component-statemachine</artifactId> </dependency> <dependency> <groupId>com.alibaba.cola</groupId> <artifactId>cola-component-test-container</artifactId> </dependency> <!-- ruleengine --> </dependencies>
dto
- 规范请求参数、规范响应结果,Api对接统一处理
<dependency>
<groupId>com.alibaba.cola</groupId>
<artifactId>cola-component-dto</artifactId>
</dependency>
请求
Query/Command
- Query类中没有任何字段,仅标识读数据请求
@Data
@EqualsAndHashCode(callSuper = true)
public class UserFindQry extends Query {
@Parameter(title = "姓名(模糊搜索)")
private String name;
}
- Command类中没有任何字段,仅标识写数据请求
@Data
@EqualsAndHashCode(callSuper = true)
public class UserAddCmd extends Command {
@Schema(title = "姓名")
@NotBlank(message = "name不能为空")
private String name;
@Schema(title = "性别")
@NotEmpty(message = "sex不能为空")
private Sex sex;
@Schema(title = "密码")
@NotBlank(message = "password不能为空")
private String password;
}
PageQuery
PageQuery是分页请求,包含了分页需要的字段
- int pageIndex: 页码,默认1
- int pageSize: 页面大小,默认10
- String orderBy: 排序字段
- String orderDirection: 排序方向,"ASC"/"DESC"
- String groupBy: 分组
- boolean needTotalCount: 是否显示总行数
@Data
@EqualsAndHashCode(callSuper = true)
public class UserPageQry extends PageQuery {
@Parameter(description = "姓名")
private String name;
@Parameter(description = "性别")
private Sex sex;
}
响应
- Response是所有响应类的基类,理论上返回值都可以用Response
但是建议写成"SingleResponse<...>"这样的子类,Swagger文档生成的响应值更加明确,有利于团队协作
Response
- 响应结果,所有响应的基类,即所有响应必定有以下字段
其他系统对接时做统一解析
- HTTP对接,使用状态码判断结果
- RPC对接,使用"success"判断结果
{ "success": true, "errCode": "string", "errMessage": "string" }
示例:无需返回值的结果
public Response delete(Long id) { // 直接响应成功 return Response.buildSuccess(); // 可直接响应失败,但一般用在异常处理中,配合响应码使用 // return Response.buildFailure("UNKNOWN_ERROR","错误信息"); }
SingleResponse
返回一个对象,格式如下
{ "success": true, "errCode": null, "errMessage": null, "data": null }
示例:返回用户详情
public SingleResponse<UserDetailCO> getDetail(Long id) { UserDetailCO detailCO = ...; // 返回一个对象结果 return SingleResponse.of(detailCO); }
MultiResponse
返回列表,格式如下
{ "success": true, "errCode": null, "errMessage": null, "empty": true, "notEmpty": false, "data": [] }
示例:返回所有用户
public MultiResponse<UserDetailCO> getAll() { List<UserDetailCO> allUser = userService.getAll(); return MultiResponse.of(allUser); }
PageResponse
返回分页信息,格式如下
{ "success": true, "errCode": null, "errMessage": null, "empty": true, "notEmpty": false, "pageIndex": 1, "pageSize": 10, "totalPages": 0, "totalCount": 0, "data": [] }
示例:返回用户分页
public PageResponse<UserPageCO> getPage(UserPageQry qry) { List<UserPageCO> list = ...; int totalCount = ...; return PageResponse.of(list, totalCount, qry.getPageSize(), qry.getPageIndex()); }
exception
官网定义:https://github.com/alibaba/COLA/tree/master/cola-components/cola-component-exception
BizException: 业务异常,有明确业务语义,不需要记录Error日志,不需要Retry
- 如:请求参数错误,账户余额不足等
SysException: 已知的系统异常,需要记录Error日志,可以Retry
- 如:数据库无法连接,RPC调用失败等
- Exception: 未知的其它异常,需要完整的Error Stack日志,可以Retry
<dependency>
<groupId>com.alibaba.cola</groupId>
<artifactId>cola-component-exception</artifactId>
</dependency>
业务抛出异常
- 使用COLA中的Assert抛出BizException异常
import com.alibaba.cola.exception.BizException;
import com.alibaba.cola.exception.SysException;
import com.alibaba.cola.exception.Assert;
// 直接抛出异常
throw new BizException("这里写业务错误信息");
throw new BizException("UNKNOWN_ERROR","这里写业务错误信息");
throw new SysException("这里写系统错误信息");
throw new SysException("SYSTEM_ERROR","这里写系统错误信息");
// Assert不通过时,抛出BizException异常
Assert.isFalse(user == null, "user不能为null");
// 自定义错误码,默认错误码是"BIZ_ERROR"
Assert.isFalse(user == null, "DATA_NOR_FOUND_ERROR", "user不能为null");
全局异常捕捉
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
@ResponseBody
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(BizException.class)
public Response handleBizException(BizException e) {
// 业务异常,无需记录日志
return Response.buildFailure(e.getErrCode(), e.getMessage());
}
@ResponseBody
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(SysException.class)
public Response handleSysException(SysException e) {
// 已知系统异常,打印报错信息
log.warn("已知系统异常:{} {}", e.getErrCode(), e.getMessage());
return Response.buildFailure(e.getErrCode(), e.getMessage());
}
@ResponseBody
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(Exception.class)
public Response handleException(Exception e) {
// 未知系统异常,打印堆栈信息
log.error("未知系统异常: {}", e.getMessage(), e);
return Response.buildFailure("UNKNOWN_ERROR", e.getMessage());
}
}
catchlog-starter
- 使用aop打印方法入参出参,以及耗时
- 官方说明:https://github.com/alibaba/COLA/tree/master/cola-components/cola-component-catchlog-starter
- @CatchAndLog注解在类上
- 注意fastjson的版本,是fastjson的2.x版本,而不是fastjson2
<!-- cola示例放在app包 -->
<dependency>
<groupId>com.alibaba.cola</groupId>
<artifactId>cola-component-catchlog-starter</artifactId>
</dependency>
<!-- 打印日志依赖fastjson-2.x版本,底层为fastjson2的兼容版本 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>2.0.51</version>
</dependency>
- 入口类增加扫描配置"com.alibaba.cola"
@SpringBootApplication(scanBasePackages = {"com.xxc.demo", "com.alibaba.cola"})
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
start/resource/logback-spring.xml
- 日志级别为"DEBUG"
<!-- 日志记录组件的日志 -->
<logger name="com.alibaba.cola.catchlog" level="DEBUG" />
需要的类中注解
- @CatchAndLog注解在类上,因为aop匹配使用@within(),匹配类注解
// 或者放在Controller层
@CatchAndLog // aop匹配使用@within,匹配类注解
public class UserServiceImpl implements UserService{
// ...
}
打印日志示例如下
- 打印请求参数、响应解雇、耗时
# 正常响应日志
DEBUG c.alibaba.cola.catchlog.CatchLogAspect : START PROCESSING: UserServiceImpl.getPage(..)
DEBUG c.alibaba.cola.catchlog.CatchLogAspect : REQUEST: {"pageIndex":1,"pageSize":10}
#...其他日志
DEBUG c.alibaba.cola.catchlog.CatchLogAspect : RESPONSE: {"data":{"current":1,"pages":0,"records":[{"age":18,"id":1,"name":"老王"},{"age":18,"id":2,"name":"老王"},{"age":0,"id":3,"name":"string"}],"size":10,"total":0},"success":true}
DEBUG c.alibaba.cola.catchlog.CatchLogAspect : COST: 520ms
# 报错日志
DEBUG c.alibaba.cola.catchlog.CatchLogAspect : START PROCESSING: UserServiceImpl.getPage(..)
DEBUG c.alibaba.cola.catchlog.CatchLogAspect : REQUEST: {"pageIndex":1,"pageSize":10}
WARN c.alibaba.cola.catchlog.CatchLogAspect : BIZ EXCEPTION : 故意报错
ERROR c.alibaba.cola.catchlog.CatchLogAspect : 故意报错
# ...报错堆栈
WARN c.a.c.catchlog.ApplicationContextHelper : No bean found for com.alibaba.cola.catchlog.ResponseHandlerI
DEBUG c.alibaba.cola.catchlog.CatchLogAspect : RESPONSE: {"errCode":"BIZ_ERROR","errMessage":"故意报错","success":false}
DEBUG c.alibaba.cola.catchlog.CatchLogAspect : COST: 227ms
domain-starter
- 使用@Entity注解scope为"prototype"的Bean
- DomainFactory实例化Bean
<!-- cola archetypes生成 -->
<dependency>
<groupId>com.alibaba.cola</groupId>
<artifactId>cola-component-domain-starter</artifactId>
</dependency>
- 入口类增加扫描配置"com.alibaba.cola"
@SpringBootApplication(scanBasePackages = {"com.xxc.demo", "com.alibaba.cola"})
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
- 注解为@Entity,scope为"prototype"的Bean
import com.alibaba.cola.domain.Entity;
@Entity
public class Heartbeat{
// ...
}
- 使用DomainFactory实例化一个对象
@Component
public class HeartbeatExe{
@Async
public void execute(){
// 获取新对象
Heartbeat heartbeat = DomainFactory.create(Heartbeat.class);
//...
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。