当前位置: 首页 > news >正文

项目开发手册-项目结构

目前企业微服务开发项目结构有两种模式:

  • 1)项目下的每一个微服务,都创建为一个独立的Project,有独立的Git仓库,尽可能降低耦合
  • 2)项目创建一个Project,项目下的每一个微服务都是一个Module,方便管理

方案一更适合于大型项目,架构更为复杂,管理和维护成本都比较高;

方案二更适合中小型项目,架构更为简单,管理和维护成本都比较低;

第二种模式如图所示

对应到我们项目中每个模块及功能如下:

微服务module中如果有对外暴露的Feign接口,需要定义到tj-api模块中:

实体类规范

所有实体类按照所处领域不同,划分为4种不同类型:

  • DTO:数据传输对象,在客户端与服务端间传递数据,例如微服务之间的请求参数和返回值、前端提交的表单
  • PO:持久层对象,与数据库表一一对应,作为查询数据库时的返回值
  • VO:视图对象,返回给前端用于封装页面展示的数据
  • QUERY:查询对象,一般是用于封装复杂查询条件

例如交易服务:

依赖注入

Spring提供了依赖注入的功能,方便我们管理和使用各种Bean,常见的方式有:

  • 字段注入(@Autowired@Resource
  • 构造函数注入
  • set方法注入

在以往代码中,我们经常利用Spring提供的@Autowired注解来实现依赖注入:

不过,这种模式是不被Spring推荐的,Spring推荐的是基于构造函数注入,像这样:

但是,如果需要注入的属性较多,构造函数就会非常臃肿,代码写起来也比较麻烦。

好在Lombok提供了一个注解@RequiredArgsConstructor,可以帮我们生成构造函数,简化代码:

这样一来,不管需要注入的字段再多,我们也只需要一个注解搞定:

异常处理

在项目运行过程中,或者业务代码流程中,可能会出现各种类型异常,为了加以区分,我们定义了一些自定义异常对应不同场景:

在开发业务的过程中,如果出现对应类型的问题,应该优先使用这些自定义异常。

当微服务抛出这些异常时,需要一个统一的异常处理类,同样在tj-common模块中定义了:

@RestControllerAdvice
@Slf4j
public class CommonExceptionAdvice {@ExceptionHandler(DbException.class)public Object handleDbException(DbException e) {log.error("mysql数据库操作异常 -> ", e);return processResponse(e.getStatus(), e.getCode(), e.getMessage());}@ExceptionHandler(CommonException.class)public Object handleBadRequestException(CommonException e) {log.error("自定义异常 -> {} , 状态码:{}, 异常原因:{}  ",e.getClass().getName(), e.getStatus(), e.getMessage());log.debug("", e);return processResponse(e.getStatus(), e.getCode(), e.getMessage());}@ExceptionHandler(FeignException.class)public Object handleFeignException(FeignException e) {log.error("feign远程调用异常 -> ", e);return processResponse(e.status(), e.status(), e.contentUTF8());}@ExceptionHandler(MethodArgumentNotValidException.class)public Object handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {String msg = e.getBindingResult().getAllErrors().stream().map(ObjectError::getDefaultMessage).collect(Collectors.joining("|"));log.error("请求参数校验异常 -> {}", msg);log.debug("", e);return processResponse(400, 400, msg);}@ExceptionHandler(BindException.class)public Object handleBindException(BindException e) {log.error("请求参数绑定异常 ->BindException, {}", e.getMessage());log.debug("", e);return processResponse(400, 400, "请求参数格式错误");}@ExceptionHandler(NestedServletException.class)public Object handleNestedServletException(NestedServletException e) {log.error("参数异常 -> NestedServletException,{}", e.getMessage());log.debug("", e);return processResponse(400, 400, "请求参数异常");}@ExceptionHandler(ConstraintViolationException.class)public Object handViolationException(ConstraintViolationException e) {log.error("请求参数异常 -> ConstraintViolationException, {}", e.getMessage());return processResponse( HttpStatus.OK.value(), HttpStatus.BAD_REQUEST.value(),e.getConstraintViolations().stream().map(ConstraintViolation::getMessage).distinct().collect(Collectors.joining("|")));}@ExceptionHandler(Exception.class)public Object handleRuntimeException(Exception e) {log.error("其他异常 uri : {} -> ", WebUtils.getRequest().getRequestURI(), e);return processResponse(500, 500, "服务器内部异常");}private Object processResponse(int status, int code, String msg){// 1.标记响应异常已处理(避免重复处理)WebUtils.setResponseHeader(Constant.BODY_PROCESSED_MARK_HEADER, "true");// 2.如果是网关请求,http状态码修改为200返回,前端基于业务状态码code来判断状态// 如果是微服务请求,http状态码基于异常原样返回,微服务自己做fallback处理return WebUtils.isGatewayRequest() ?R.error(code, msg).requestId(MDC.get(Constant.REQUEST_ID_HEADER)): ResponseEntity.status(status).body(msg);}
}

http://www.dtcms.com/a/512955.html

相关文章:

  • 数据库原理实验报告:数据库查询操作实现
  • 学习网站开发流程wordpress采集附件
  • 网站开发招标参数三亚市建设局网站公示
  • 网站后台iis配置立陶宛与俄罗斯最新消息
  • 【AI】AI评测入门(五):Evaluation 跑起来
  • GSFE层错能计算(DFT)
  • 数据结构——二十八、图的基本操作(王道408)
  • 百度分公司 网站外包中文在线っと好きだった最新版
  • 【Python OOP Diary 1.1】题目二:简单计算器,改错与优化
  • 如何用记事本做网站php网站开发工程师
  • 企业网站群建设的原因网站优化检查
  • 【JVM】详解 Class类文件的结构
  • 珠海市住房和建设局网站微网站开发 php
  • 欧美做爰视频网站工业品一站式采购平台
  • 中位数贪心|
  • 红海eHR全面智能化升级,重塑全角色智慧体验
  • 建设通网站联系电话谷歌浏览器怎么关闭2345网址导航
  • Xshell效率实战系列四:内置Xftp快速启动——从1分钟到10秒的传输革命
  • 贷款做网站公众号制作教程视频
  • 微信链接网页网站制作较好的网站建设公司
  • seo网站推广经理招聘黄冈seo顾问
  • 自助网站建设哪家效益快wordpress分享跳转插件
  • 解决Linux系统中“undeclared identifier“问题的完整指南
  • SAP SD客户物料批量维护功能分享
  • 秋实网站建设成全视频免费观看在线看动漫
  • uniapp vue 接口传值 \\ map遍历数据\\forEach \\ splice截取分隔符 \\请求携带数据向后端请求数据
  • 动态图片素材网站建站下载专用网站
  • 网站建设合同用缴印花税吗珠海网站建设的公司哪家好
  • 【GESP】C++四级真题 luogu-B4041 [GESP202409 四级] 区间排序
  • (七)React 条件渲染原理分析