Day 2 正式coding之基础模块的搭建

Day 2 正式coding之基础模块的搭建

这里会总结构建项目过程中遇到的问题,以及一些个人思考!!

学习方法:

1 github源码 + 文档 + 官网

2 内容复现 ,实际操作

项目源码同步更新到github 欢迎大家star~ 后期会更新并上传前端项目

创建父工程

新建一个jdk17的maven工程,并删掉src目录

image-20240413181927881

导入依赖文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.bootscoder</groupId><artifactId>shopping</artifactId><version>1.0-SNAPSHOT</version><!-- 为表示其为父工程,设置打包方式--><packaging>pom</packaging><!-- 子模块 --><modules></modules><properties><java.version>17</java.version><dubbo.version>3.2.4</dubbo.version><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><spring-boot.version>3.0.2</spring-boot.version><spring-cloud.version>2022.0.0</spring-cloud.version><spring-cloud-alibaba.version>2022.0.0.0</spring-cloud-alibaba.version><lombok.version>1.18.28</lombok.version><mybatis-plus.version>3.5.4</mybatis-plus.version></properties><!-- 依赖版本声明 --><dependencyManagement><dependencies><!-- Spring Cloud版本--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring-cloud.version}</version><type>pom</type><scope>import</scope></dependency><!-- Spring Cloud Alibaba版本 --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>${spring-cloud-alibaba.version}</version><type>pom</type><scope>import</scope></dependency><!-- SpringBoot版本 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>${spring-boot.version}</version><type>pom</type><scope>import</scope></dependency><!-- Dubbo版本 --><dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo-bom</artifactId><version>${dubbo.version}</version><type>pom</type><scope>import</scope></dependency><!-- lombok版本 --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>${lombok.version}</version></dependency><!-- mybatis-plus版本 --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>${mybatis-plus.version}</version></dependency></dependencies></dependencyManagement><!-- 通用依赖 --><dependencies><!-- bootstrap启动器 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-bootstrap</artifactId></dependency></dependencies><!-- 插件 --><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><source>${java.version}</source><target>${java.version}</target><encoding>${project.build.sourceEncoding}</encoding></configuration></plugin></plugins></build><!-- 依赖仓库路径 --><repositories><repository><id>public</id><name>aliyun nexus</name><url>https://maven.aliyun.com/repository/public</url><releases><enabled>true</enabled></releases></repository></repositories><!-- 插件仓库路径 --><pluginRepositories><pluginRepository><id>public</id><name>aliyun nexus</name><url>https://maven.aliyun.com/repository/public</url><releases><enabled>true</enabled></releases><snapshots><enabled>false</enabled></snapshots></pluginRepository></pluginRepositories>
</project>

创建通用模块

使用Nacos时,我们需要使用Dubbo进行服务调用,此时我们需要构建一个通用模块,在通用模块中存放服务接口。除了服务接口,我们还会存放一些实体类、工具类等通用功能,每个模块都会引用通用模块。

Dubbo进行服务调用 有两个身份: 生产者和消费者

通用模块的依赖注入

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><!-- lombok --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><!-- MyBatisPlus --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId></dependency><!-- elasticsearch --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency>
</dependencies>

配置父模块

<parent><groupId>com.bootscoder</groupId><artifactId>shopping</artifactId><version>1.0-SNAPSHOT</version><relativePath/> <!-- lookup parent from repository -->
</parent>

配置子模块

<!-- 子模块  -->
<modules><!-- 通用模块,包含实体类、服务接口、工具类等 --><module>shopping_common</module>
</modules>

流程总结

  1. pom文件改写
  2. 创建pojo文件夹,编写实体类。
  3. 由于通用模块只会被其他模块引用,而不会启动,所以可以删除启动类。
  4. 创建名为shopping的数据库,将数据库脚本导入mysql中。
  5. 在通用模块添加service包存放服务接口,添加utils包存放工具类。

创建商品服务模块

<dependencies><!-- MyBatisPlus --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId></dependency><!-- mysql驱动 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><dependency><groupId>com.bootscoder</groupId><artifactId>shopping_common</artifactId><version>0.0.1-SNAPSHOT</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!-- dubbo --><dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo-spring-boot-starter</artifactId></dependency><dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo-registry-nacos</artifactId></dependency><!-- nacos --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency>
</dependencies>
# 端口号
server:port: 9001# 日志格式
logging:pattern:console: '%d{HH:mm:ss.SSS} %clr(%-5level) ---  [%-15thread] %cyan(%-50logger{50}):%msg%n'spring:application:name: shopping_goods_service #服务名cloud:nacos:discovery:server-addr: 192.168.66.100:8848 # 注册中心地址# 数据源datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql:///shopping?serverTimezone=UTCusername: 你的namepassword: 你的密码dubbo:application:name: shopping_goods_service #服务名serialize-check-status: DISABLEcheck-serializable: falseprotocol:name: dubbo # 通讯协议port: -1 # 端口号,-1表示自动扫描可用端口。registry:address: nacos://192.168.66.100:8848 # 注册中心# 配置Mybatis-plus
mybatis-plus:global-config:db-config:# 表名前缀table-prefix: boots_# 主键生成策略为自增id-type: autoconfiguration:# 关闭列名自动驼峰命名映射规则map-underscore-to-camel-case: falselog-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 开启sql日志
spring:profiles:active: dev #环境cloud:nacos:config:server-addr: 192.168.66.100:8848namespace: 44d5da8b-b356-4aa8-b4be-49a54cb8b8eefile-extension: yamlprefix: shopping_goods_service
  1. 构建springboot
  2. pom文件依赖+父子模块指定
  3. 修改yaml
在nacos 中编写配置文件

将配置文件放到nacos中, 在项目中进行读取

image-20240414172936180

配置文件发布

在本地代码中配置 bootstrap.yml 连接nacos 配置中心

woc 这个idea 版本(2019)已经落后了???

更新后 依然起不来

马勒戈壁 说老子没配置database 傻逼

md 配置中心和本地文件命名指向不匹配,操了

更新idea后成功

image-20240414192903798

编写根据id查询品牌功能(放到goods里面)
  1. 在启动类中添加注解@EnableDiscoveryClient // 向注册中心注册该服务
    @EnableDubbo // 开启Dubbo
    @RefreshScope // 配置动态刷新
  2. 编写服务实现类
    1. 记得加dubbo 的service注解
    2. 加事务注解
  3. 编写mapper
  4. 启动类扫描mapper

image-20240414195432921

nacos 使用

提问-通用模块的细节:

  1. 这里提一个小的问题哈,为什么这里的GoodsService 可以调用common呢?
  2. 做分布式搭建后,是否仍然可以进行调用?

maven依赖引入;

需要整体打包,或者将common注册到maven的中心仓库

做完整体的流程我想模拟一下分布式调用

创建管理员端API模块

这里使用postman进行测试;没有使用过的……那你可能要Google一下了

image-20220725114012728

商城分为管理员端和用户端,用户端是用户访问的,可以查询商品、购买商品;管理员端是商家访问的,可以维护商品。由于管理员端的访问量有限,我们将管理员端的所有控制器都放入管理员端的API模块。

前端项目访问该模块的控制器,控制器返回json数据给前端。管理员端API模块并不能查询数据,它只是服务的消费者,需要连接服务的生产者才能查询到数据。

image-20240416212357763

  1. 创建名为shopping_manager_api的SpringBoot工程,添加相关依赖。

  2. 设置该工程的父工程为shopping

  3. 编写根据id 查询的controller

/*** 品牌控制器** @author bootsCoder* @date created on 2024/4/15*/
@RestController
@RequestMapping(("/brand"))
public class BrandController {@DubboReferenceprivate BrandService brandService;@GetMapping("/findById")public Brand findById(Long id){return brandService.findById(id);}
}
image-20240415181355208

API接口设置统一数据返回格式


/*** 全局统一结果配置** @author bootsCoder* @date created on 2024/4/15*/
@Data
@AllArgsConstructor
public class BaseResult<T> {// 状态码(成功:200 失败:其他)private Integer code;// 提示消息private String message;// 返回数据private T data;// 构建成功结果public static <T> BaseResult<T> ok() {return new BaseResult(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMessage(), null);}// 构建带有数据的成功结果public static <T> BaseResult<T> ok(T data) {return new BaseResult(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMessage(), data);}
}/*** 状态码** @author bootsCoder* @date created on 2024/4/15*/
@Getter
@AllArgsConstructor
public enum ResultCode {// 正常SUCCESS(200, "OK");private final Integer code;private final String message;
}@GetMapping("/findById")public BaseResult<Brand> findById(Long id){Brand brand = brandService.findById(id);return BaseResult.ok(brand);}

image-20240415182915192

统一异常处理

  • 异常信息从服务端传入消费端时,Dubbo会默认封装异常,绕过我们的全局异常处理器,所以在通用模块禁用Dubbo异常封装,

  • 由于新版Dubbo默认关闭对象序列化,使得异常信息不能从服务端传入消费端(会发生什么呢?),所以在通用模块开启Dubbo序列化:

# 禁用Dubbo异常封装,使用自定义异常处理
dubbo.provider.filter=-exception
# 开启Dubbo序列化
dubbo.application.serialize-check-status=DISABLE

为了让所有项目都可以加载全局异常处理类,可以在通用模块的resources目录下建立META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件,添加如下内容:

com.bootscoder.shopping_common.result.GlobalExceptionHandler

在Dubbo这样的分布式服务框架中,如果默认关闭了对象序列化,就会影响异常信息从服务端传到消费端的能力。具体表现为:

  1. 异常信息丢失:当服务端发生异常时,这些异常信息需要通过网络传输到消费端。对象序列化是这一过程中的关键,它允许复杂的对象数据转换为字节流,以便可以通过网络传输。如果序列化被关闭,异常对象不能被有效地转换和传输,导致消费端无法接收到完整的异常信息。
  2. 通用异常代替:在没有获取到具体异常信息的情况下,消费端可能只能接收到一些非常通用的异常,例如java.rmi.RemoteException。这意味着消费端得到的错误信息不具体,无法准确反映服务端发生的实际问题。
  3. 错误处理困难:缺乏具体的异常信息会使得消费端难以进行针对性的错误处理或调试。这可能会增加问题诊断和解决的时间和复杂性,影响服务的整体可靠性和用户体验。
  4. 服务降级处理:在一些情况下,如果异常信息不能正确传递,系统可能需要依赖预定义的服务降级策略。这些策略虽然能保持系统运行,但可能不是最优解决方案。

image-20240416212345908


/*** 自定义异常** @author bootsCoder* @date created on 2024/4/15*/
@AllArgsConstructor
@NoArgsConstructor
@Data
public class MyException extends RuntimeException {// 状态码private Integer code;// 错误消息private String msg;public MyException(ResultCode resultCode){this.code = resultCode.getCode();this.msg = resultCode.getMessage();}
}   
package com.bootscoder.shopping_common.result;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;/*** 统一异常处理** @author bootsCoder* @date created on 2024/4/15*/
@RestControllerAdvice
public class GlobalExceptionHandler {// 处理业务异常@ExceptionHandler(MyException.class)public BaseResult defaultExceptionHandler(MyException e){BaseResult baseResult = new BaseResult(e.getCode(),e.getMsg(),null);return baseResult;}// 处理系统异常@ExceptionHandler(Exception.class)public BaseResult defaultExceptionHandler(HttpServletRequest req, HttpServletResponse resp, Exception e) {e.printStackTrace();BaseResult baseResult = new BaseResult(ResultCode.SYSTEM_ERROR.getCode(),ResultCode.SYSTEM_ERROR.getMessage(),null);return baseResult;}
}@GetMapping("/findById")public BaseResult<Brand> findById(Long id){/*** 测试异常处理器*/if (id == 0){long i = 1/id;} else if (id == -1 ) {throw new MyException(ResultCode.PARAMETER_ERROR);}Brand brand = brandService.findById(id);return BaseResult.ok(brand);}
{"code": 500,"message": "系统异常","data": null
}
{"code": 601,"message": "参数异常","data": null
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/822343.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring基础篇-快速面试笔记(速成版)

文章目录 1. Spring概述2. 控制反转&#xff08;IoC&#xff09;2.1 Spring声明Bean对象的方式2.2 Spring的Bean容器&#xff1a;BeanFactory2.3 Spring的Bean生命周期2.4 Spring的Bean的注入方式 3. Spring的事件监听器&#xff08;Event Listener&#xff09;3.1 Spring内置事…

自学Java的第二十四次笔记

一,方法重载 1.基本介绍 java 中允许同一个类中&#xff0c;多个同名方法的存在&#xff0c;但要求 形参列表不一致&#xff01; 比如&#xff1a; System.out.println(); out 是 PrintStream 类型 2.重载的好处 1) 减轻了起名的麻烦 2) 减轻了记名的麻烦 3.快速入门案…

认识海康摄像头的编码信息以及使用等

认识海康摄像头的编码信息以及使用等 主要是来源一下文章&#xff1a; 海康摄像头、NVR命名规则-弱电新人学习&#xff01; - 知乎 大体是分了三类&#xff0c;当然海康的产品实在是有点多&#xff0c;没找见官方权威的解答&#xff0c;参考着先看看。 网络摄像机、网络球机…

浅谈Java JVM

Java虚拟机&#xff08;Java Virtual Machine&#xff0c;简称JVM&#xff09;是Java语言的核心组成部分&#xff0c;它是一个抽象的计算机&#xff0c;负责执行Java字节码指令。JVM是Java平台无关性的基石&#xff0c;它为Java代码提供了一个标准的运行环境&#xff0c;使Java…

golang-基础语法

make 和 new 的区别 make 和 new 都是用来分配内存 make 只能对 slice map channel 进行初始化结构体实例。new 可以对任意类型进行初始化make 用于分配数据对象的具体实例&#xff0c;new 用于分配数据类型的默认值&#xff0c;并返回该数据的指针。 new 出来的 slice 、ma…

html5测试题整理--针对标签的概念性,我们究竟还要学习哪些软件测试知识

先自我介绍一下&#xff0c;小编浙江大学毕业&#xff0c;去过华为、字节跳动等大厂&#xff0c;目前阿里P7 深知大多数程序员&#xff0c;想要提升技能&#xff0c;往往是自己摸索成长&#xff0c;但自己不成体系的自学效果低效又漫长&#xff0c;而且极易碰到天花板技术停滞…

Ubuntu20.04版本命令行设置挂载磁盘,并设置开机自动挂载

最近部署应用 系统是Ubuntu20.4版本的Linux系统&#xff0c;加了数据盘&#xff0c;需要格式化后挂载&#xff0c;记录下&#xff1a; Linux 数据盘挂载(采用 parted 分区工具)-格式化为 ext4 1. 初始化 Linux 数据盘 挂载数据盘后或者随实例创建时一并创建的数据盘&#xff…

使用SpringBoot3+Vue3开发公寓管理系统

项目介绍 公寓管理系统可以帮助公寓管理员更方便的进行管理房屋。功能包括系统管理、房间管理、租户管理、收租管理、房间家具管理、家具管理、维修管理、维修师傅管理、退房管理。 功能介绍 系统管理 用户管理 对系统管理员进行管理&#xff0c;新增管理员&#xff0c;修改…

碳课堂|碳关税是什么?企业如何从容应对?

2023年10月1日&#xff0c;欧盟碳边境调节机制&#xff08;CBAM&#xff09;法规&#xff0c;即全球首个“碳关税”开始实施。据世界银行研究报告称&#xff0c;如果“碳关税”全面实施&#xff0c;在国际市场上&#xff0c;中国制造可能将面临平均26%的关税&#xff0c;出口量…

Android JetPack Compose+Room----实现搜索记录功能

文章目录 需求概述功能展示实现搜索功能使用的技术1.Android Jetpack room2.Android JetPack Compose 代码实现编写搜索界面接入Room实现搜索功能的管理引入依赖定义包结构定义操作表的Dao类定义数据库的基础配置定义数据库的Dao管理类使用数据库升级 源码地址 需求概述 搜索功…

台灯目前口碑最好的护眼灯有哪些?分享多款高口碑护眼灯

根据数据表明中国近视患者人数已达到7亿&#xff0c;关于视力问题&#xff0c;而儿童及中小学生居多&#xff0c;关于视力问题&#xff0c;很多人都归咎于幼时学习时的用眼时间过长&#xff0c;但这只是其中的一部分&#xff0c;不合适的光源环境影响也是非常大的&#xff0c;尤…

006Node.js cnpm的安装

百度搜索 cnpm,进入npmmirror 镜像站https://npmmirror.com/ cmd窗口输入 npm install -g cnpm --registryhttps://registry.npmmirror.com

Fluke ADPT连接器(隔离版)----发布2

代替手工记录、记录后在整理的麻烦&#xff0c;轻点鼠标&#xff08;单次采集、自动时间间隔采集自由选择&#xff09;即可完成&#xff0c;测试数据导出图片、导出数据到EXCEL文件随意选择&#xff1b; 所需设备&#xff1a; 1、Fluke ADPT连接器&#xff1b;内附链接 ● …

基于小程序实现的餐饮外卖系统

作者主页&#xff1a;Java码库 主营内容&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app等设计与开发。 收藏点赞不迷路 关注作者有好处 文末获取源码 技术选型 【后端】&#xff1a;Java 【框架】&#xff1a;spring…

闲不住,手写一个数据库文档生成工具

shigen坚持更新文章的博客写手&#xff0c;擅长Java、python、vue、shell等编程语言和各种应用程序、脚本的开发。记录成长&#xff0c;分享认知&#xff0c;留住感动。 个人IP&#xff1a;shigen 逛博客的时候&#xff0c;发现了一个很有意思的文章&#xff1a;数据库表结构导…

xxl-job使用自动注册节点,ip不对,如何解决????

很明显这时我们本机的ip和我们xxl-job自动注册的ip是不一致的&#xff0c;此时该如何处理呢&#xff1f;&#xff1f;&#xff1f;&#xff1f; 方法一&#xff1a;在配置文件中&#xff0c;将我们的ip固定写好。 ### xxl-job executor server-info xxl.job.executor.ip写你的…

解决EasyPoi导入Excel获取不到第一列的问题

文章目录 1. 复现错误2. 分析错误2.1 导入的代码2.2 DictExcel实体类2.2 表头和标题3. 解决问题1. 复现错误 使用EasyPoi导入数据时,Excel表格如下图: 但在导入时,出现如下错误: name为英文名称,在第一列,Excel表格有值,但导入的代码中为null,就很奇怪? 2. 分析错误 …

线上频繁fullgc问题-SpringActuator的坑

整体复盘 一个不算普通的周五中午&#xff0c;同事收到了大量了cpu异常的报警。根据报警表现和通过arthas查看&#xff0c;很明显的问题就是内存不足&#xff0c;疯狂无效gc。而且结合arthas和gc日志查看&#xff0c;老年代打满了&#xff0c;gc不了一点。既然问题是内存问题&…

翱途O2OA新手上路-服务器下载及私有云部署

本篇主要简要描述从官网下载服务器&#xff0c;进行部署&#xff0c;启动的过程&#xff0c;并且描述在部署过程中常见的问题与报错以及云服务器安全策略配置和O2OA服务器端口修改的方式。 O2OA部署的服务器要求不高&#xff0c;一般使用4C8G以上的服务器均可正常运行。 一、检…

Spark_SparkSql写入Oracle_Undefined function.....将长字符串写入Oracle中方法..

在使用Spark编写代码将读库处理然后写入Oracle中遇到了诸多小bug,很磨人&#xff0c;好在解决了。shit!! 实测1&#xff1a;TO_CLOB(a3) 代码样例 --这是一个sparksql写入hive的一个小逻辑&#xff0c;我脱敏了噻 SELECT a1, a2, TO_CLOB(a3) AS clob_data, TO_DATE(a4) AS …