木字楠后台管理系统开发(1):SpringBoot项目初始化并引入基础文件

news2024/11/18 11:28:27

在这里插入图片描述


🎶 文章简介:木字楠后台管理系统(1):SpringBoot项目初始化并引入基础文件
💡 创作目的:为了带大家完整的体验木字楠后台管理系统模版的开发流程
☀️ 今日天气:天气☁️很好。太阳晒在身上暖暖的
📝 每日一言:多情却被无情恼,今夜还如昨夜长。


文章目录

  • 🚗 1、新建一个SpringBoot项目
  • 🚕 2、项目结构完善
    • 🚙 2-1、基础依赖引入
    • 🏎️ 2-2、常用结果枚举类
    • 🚐 2-3、统一结果集处理类
    • 🚌 2-4、统一异常处理类
    • 🚎 2-5、统一日志信息处理

🚗 1、新建一个SpringBoot项目

  • 使用IDEA编辑器新建一个 SpringBoot 项目
  • 项目名称自定义(eg:MuZiNan-Template)
  • Jdk 版本使用 1.8 的版本

在这里插入图片描述

  • SpringBoot版本选择默认,创建成功之后会在 pom文件 中修改为 2.5.5 版本
  • 依赖引入选择Web依赖即可

在这里插入图片描述

这样我们就已经成功新建了一个SpringBoot项目了。

接下来我们对SpriingBoot 的部分配置信息进行修改。

  • SpringBoot 版本
  • 项目基础描述信息(版本、描述信息大家可自定定义)

在这里插入图片描述

🚕 2、项目结构完善

🚙 2-1、基础依赖引入

首先我们需要引入项目中所必须的一些基础依赖,eg: MysqlLombokFastJson

    <!--==============  项目版本号规定 ===============-->
    <properties>
        <java.version>1.8</java.version>
        <!--==============  数据库依赖  ==================-->
        <mysql.version>8.0.29</mysql.version>
        <!--==============  工具依赖  ==================-->
        <lombok.version>1.18.24</lombok.version>
        <fastjson.version>2.0.7</fastjson.version>
    </properties>

   <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--================== 数据库依赖 =======================-->
        <!-- mysql8 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${mysql.version}</version>
        </dependency>
        <!--================== 工具依赖 =======================-->
        <!--Lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${lombok.version}</version>
        </dependency>
        <!-- 阿里JSON解析器 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>${fastjson.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

🏎️ 2-2、常用结果枚举类

在项目中经常会返回一些统一的结果(比如:操作成功,操作失败…),我们可以将这些信息定义在常用的枚举类中,方便后续使用。我们的常用结果枚举类也会结合结果集处理器自定义异常类全局异常处理类进行使用。

注意:枚举类中不需要setter方法,我们仅提供getter方法即可。

/**
 * @author 木字楠
 * @version 1.0
 * @date 2022/11/24
 * @description 常用结果枚举类
 */
@Getter
@AllArgsConstructor
public enum HttpCodeEnum {
    //==================== 登录相关枚举 ======================
    /**
     * 登陆超时
     */
    USER_LOGIN_TIME_OUT(100, "登陆超时"),
    /**
     * 用户未登录
     */
    USER_NOT_LOGIN(101, "用户未登录,请先进行登录"),
    /**
     * 账户被禁用,请联系管理员解决
     */
    ACCOUNT_IS_DISABLED(102, "账户被禁用,请联系管理员解决"),
    /**
     * 用户信息加载失败
     */
    USER_INFO_LOAD_FAIL(103, "用户信息加载失败"),
    /**
     * 用户身份信息获取失败
     */
    USER_IDENTITY_LOAD_FAIL(104, "用户身份信息获取失败"),
    /**
     * 用户名不能为空
     */
    USERNAME_CAN_NOT_BE_EMPTY(105, "用户名不能为空"),
    /**
     * 用户名或密码错误
     */
    USERNAME_OR_PASSWORD_ERROR(106, "用户名或密码错误"),
    /**
     * 用户登录成功
     */
    USER_LOGIN_SUCCESS(108, "用户登录成功"),
    /**
     * 用户注销成功
     */
    USER_LOGOUT_SUCCESS(109, "用户注销成功"),
    //==================== 注册相关枚举 ======================
    /**
     * 验证码错误
     */
    CAPTCHA_ERROR(300, "验证码错误"),
    /**
     * 验证码过期
     */
    CAPTCHA_ALREADY_EXPIRE(301, "验证码已过期"),
    /**
     * 用户名已存在
     */
    USERNAME_ALREADY_EXISTED(302, "用户名已存在"),
    /**
     * 参数格式不合法
     */
    PARAMETER_VALID_ERROR(600, "参数格式不合法"),
    //======================= 其他枚举 ==============================
    /**
     * 没有权限
     */
    PERMISSION_NOT_DEFINED(403, "您没有操作权限"),
    /**
     * 操作成功
     */
    OPERATOR_IS_SUCCESS(200, "操作成功"),
    /**
     * 操作失败
     */
    OPERATOR_IS_FAILED(500, "操作失败"),
    /**
     * 未知异常
     */
    UNKNOWN_ERROR(600, "未知异常");


    /**
     * 状态码
     */
    private final int code;
    /**
     * 返回信息
     */
    private final String message;

}

🚐 2-3、统一结果集处理类

在前后端分离项目中,前端开发同学 与 后端开发同学 会约定好接口返回结果的数据结构。这样方便前端开发童鞋对于网络请求结果的判断以及设置统一的数据接受方式。

至于这里使用到了泛型,这是为了方便返回data数据类型的规定,当我们所需要的返回对象是什么类型,只需要提前规定即可。

但是我们也会发现一个问题,我们的统一结果集处理类确实可以返回对象数据和列表数据,但是返回的结果中没有总条数数据,这样对我们进行分页查询时就会很麻烦,所以我又新增了一个分页结果处理类

# 本项目中呢我们所约定的数据结构如下:
{
    code: 200,
    success: true,      
    message: "返回提示信息",
    data:{}
}
/**
 * @author: MuZiNan
 * @createDate: 2022/11/24
 * @description: 统一结果集处理器
 * @version: 1.0
 */
@Data
public class ResponseResult<T> {

    /**
     * 请求状态
     */
    private Boolean success;

    /**
     * 状态码
     */
    private Integer code;

    /**
     * 状态信息
     */
    private String message;

    /**
     * 数据信息
     */
    private T data;

    /**
     * 私有构造
     *
     * @param success 请求状态
     * @param code    状态码
     * @param message 状态信息
     * @param data    数据
     * @param <T>     泛型数据
     * @return 结果集处理器
     */
    private static <T> ResponseResult<T> response(Boolean success, Integer code, String message, T data) {
        ResponseResult<T> result = new ResponseResult<>();
        result.setSuccess(success);
        result.setCode(code);
        result.setMessage(message);
        result.setData(data);
        return result;
    }

    /**
     * 请求成功返回(一)
     *
     * @param code    状态码
     * @param message 状态信息
     * @param data    数据
     * @param <T>     泛型数据
     * @return 结果集处理器
     */
    public static <T> ResponseResult<T> success(Integer code, String message, T data) {
        return response(true, code, message, data);
    }

    /**
     * 请求成功返回(二)
     *
     * @param message 状态信息
     * @param data    数据
     * @param <T>     泛型数据
     * @return 结果集处理器
     */
    public static <T> ResponseResult<T> success(String message, T data) {
        return response(true, HttpCodeEnum.OPERATOR_IS_SUCCESS.getCode(), message, data);
    }

    /**
     * 请求成功返回(三)
     *
     * @param message 状态信息
     * @param <T>     泛型数据
     * @return 结果集处理器
     */
    public static <T> ResponseResult<T> success(String message) {
        return response(true, HttpCodeEnum.OPERATOR_IS_SUCCESS.getCode(), message, null);
    }

    /**
     * 请求成功返回(四)
     *
     * @param httpCodeEnum 状态枚举
     * @param <T>          泛型数据
     * @return 结果集处理器
     */
    public static <T> ResponseResult<T> success(HttpCodeEnum httpCodeEnum) {
        return response(true, httpCodeEnum.getCode(), httpCodeEnum.getMessage(), null);
    }

    /**
     * 请求成功返回(五)
     *
     * @param httpCodeEnum 状态枚举
     * @param data         数据
     * @param <T>          泛型数据
     * @return 结果集处理器
     */
    public static <T> ResponseResult<T> success(HttpCodeEnum httpCodeEnum, T data) {
        return response(true, httpCodeEnum.getCode(), httpCodeEnum.getMessage(), data);
    }

    /**
     * 请求成功返回(六)
     * @param data 数据
     * @return 结果集处理器
     * @param <T> 泛型数据
     */
    public static <T> ResponseResult<T> success( T data) {
        return response(true, HttpCodeEnum.OPERATOR_IS_SUCCESS.getCode(),HttpCodeEnum.OPERATOR_IS_SUCCESS.getMessage(), data);
    }


    /**
     * 请求失败返回(一)
     *
     * @param code    状态码
     * @param message 状态信息
     * @param data    数据
     * @param <T>     泛型数据
     * @return 结果集处理器
     */
    public static <T> ResponseResult<T> fail(Integer code, String message, T data) {
        return response(false, code, message, data);
    }

    /**
     * 请求失败返回(二)
     *
     * @param message 状态信息
     * @param data    数据
     * @param <T>     泛型数据
     * @return 结果集处理器
     */
    public static <T> ResponseResult<T> fail(String message, T data) {
        return response(false, HttpCodeEnum.OPERATOR_IS_FAILED.getCode(), message, data);
    }

    /**
     * 请求失败返回(三)
     *
     * @param message 状态信息
     * @param <T>     泛型数据
     * @return 结果集处理器
     */
    public static <T> ResponseResult<T> fail(String message) {
        return response(false, HttpCodeEnum.OPERATOR_IS_FAILED.getCode(), message, null);
    }

    /**
     * 请求失败返回(四)
     *
     * @param httpCodeEnum 状态枚举
     * @param <T>          泛型数据
     * @return 结果集处理器
     */
    public static <T> ResponseResult<T> fail(HttpCodeEnum httpCodeEnum) {
        return response(false, httpCodeEnum.getCode(), httpCodeEnum.getMessage(), null);
    }

}


分页结果处理类也是用到了泛型,效果同上。当我们需要处理分页查询的时候可以将PageResult整个对象返回出去即可。

/**
 * @author 木字楠
 * @version 1.0
 * @description 分页结果处理类
 * @date 2022/11/24
 */
@Data
@AllArgsConstructor
public class PageResult<T> {

    /**
     * 总数据量
     */
    private long totalCount;

    /**
     * 数据列表
     */
    private List<T> dataList;

}

🚌 2-4、统一异常处理类

统一异常处理的目的是为了防止直接将后台的报错信息返回给前端,这样对于前端的同学并不友好,而且对于后端同学的排错也不方便。

  • 自定义异常类
  • 全局异常处理类
/**
 * @author 木字楠
 * @version 1.0
 * @date 2022/11/24
 * @description 基础异常处理类
 */
@Getter
public class BaseException extends RuntimeException {

    /**
     * 状态码
     */
    private final Integer code;

    /**
     * 报错信息
     */
    private final String message;

    /**
     * 全参构造方法
     *
     * @param code    状态码
     * @param message 报错信息
     */
    public BaseException(Integer code, String message) {
        this.code = code;
        this.message = message;
    }

    /**
     * 构造方法
     *
     * @param message 报错信息
     */
    public BaseException(String message) {
        this(HttpCodeEnum.OPERATOR_IS_FAILED.getCode(), message);
    }

    /**
     * 构造方法
     * @param httpCodeEnum http枚举类
     */
    public BaseException(HttpCodeEnum httpCodeEnum) {
        this(httpCodeEnum.getCode(), httpCodeEnum.getMessage());
    }

}

统一异常信息处理类:

  • 被**@RestControllerAdvice**注解可以使用 @ExceptionHandler,@InitBinder和@ModelAttribute这些注解
  • **@ExceptionHandler(Exception.class)**可以捕获到所传入的异常类型,例如NullPointerException、FileNotFoundException等异常(比如下述代码中,第一个可以捕获所有的异常,Exception是所有异常的父类。第二个尽可以捕获BaseException类型的异常)
  • 捕获到异常之后我们选择使用统一结果集类进行返回提示系统出现异常
/**
 * @author: MuZiNan
 * @createDate: 2022/11/24
 * @description: 统一异常信息处理
 * @version: 1.0
 */
@Slf4j
@RestControllerAdvice
public class GlobalException {

    /**
     * 全局异常处理
     *
     * @param e 异常信息
     * @return 错误信息
     */
    @ExceptionHandler(Exception.class)
    public ResponseResult<?> globalException(Exception e) {
        log.error("异常信息 => {}", e.getMessage());
        e.printStackTrace();
        return ResponseResult.fail(HttpCodeEnum.OPERATOR_IS_FAILED.getMessage());
    }

    /**
     * 基础异常处理
     *
     * @param baseException 基础异常信息类
     * @return 错误结果
     */
    @ExceptionHandler(BaseException.class)
    public ResponseResult<?> baseException(BaseException baseException) {
        log.error("异常信息 => {}", baseException.getMessage());
        return ResponseResult.fail(baseException.getMessage());
    }

}

🚎 2-5、统一日志信息处理

我们这里使用Log4j2来进行日志的打印,首先我们引入Log4fj2的依赖,因为我们的父工程是springboot项目,不设置版本默认使用父工程的版本(即:2.5.5版本)

        <!--==============  SpringBoot相关依赖 ===============-->
        <!-- web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- Log4j2 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-log4j2</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

我们需要在resources目录下引入 log4j2.xml 文件,大家默认使用如下内容即可。(切记 文件名称不能输错必须为log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>

<!-- status:用来指定log4j本身的打印日志级别,monitorInterval:指定log4j自动重新配置的监测间隔时间 -->
<configuration status="WARN" monitorInterval="30">
    <!-- 自己设置属性,后面通过${}来访问 -->
    <properties>
        <!--<property name="LOG_HOME">${web:rootDir}/logs</property>-->
        <property name="LOG_HOME">/opt/logs</property>
        <!--日志名称-->
        <property name="LOG_NAME">nanjustar-server-logs</property>
        <!--日志格式-->
        <property name="LOG_FORMAT">[%d{yyyy-MM-dd HH:mm:ss.SSS}] %p %t %c[%L] - %m %n</property>
        <property name="LOG_FORMAT_CONSOLE">%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight{%-5level} [%t] %highlight{%c{1.}.%M(%L)}: %msg%n%throwable</property>
        <!--备份目录- 根据年月建立文件夹 -->
        <property name="BACKUP_HOME">${LOG_HOME}/$${date:yyyy-MM}</property>
        <!--备份频率-->
        <property name="BACK_HZ">%d{yyyy-MM-dd}</property>
    </properties>
    <appenders>
        <!--控制台日志-->
        <console name="console" target="SYSTEM_OUT">
            <!--输出日志的格式-->
            <PatternLayout pattern="${LOG_FORMAT_CONSOLE}" disableAnsi="false" noConsoleNoAnsi="false"/>
        </console>

    </appenders>

    <loggers>
        <!--根日志配置-->
        <root level="info">
            <appender-ref ref="console"/>
            <appender-ref ref="infoLog"/>
            <appender-ref ref="warnLog"/>
            <appender-ref ref="errorLog"/>
        </root>
    </loggers>
</configuration>


引入之后我们会发现项目启动的时候会出现依赖冲突的问题,这是由于Springboot web模块自带logback与log4j2冲突问题及配置,解决方法呢是我们将web模块中的logback模块进行排除,不再使用web模块中的logback

排除需要使用到<exclusions></exclusions>

       <!--==============  SpringBoot相关依赖 ===============-->
       <!-- web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <artifactId>logback-classic</artifactId>
                    <groupId>ch.qos.logback</groupId>
                </exclusion>
                <exclusion>
                    <groupId>org.apache.logging.log4j</groupId>
                    <artifactId>log4j-to-slf4j</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

至此,我们的基础配置已经全部完成。


在这里插入图片描述

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

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

相关文章

ChatGPT到底是个啥?它会让我们失业么?

谈起AI届&#xff0c;几家大公司是无论如何都不能不提及的&#xff0c;谷歌的GoogleX与DeepMind (下围棋那个)、Meta的FAIR (Resnet提出者恺明所就职的)、OpenAI (搞大模型的领先公司&#xff0c;代表作是GPT&#xff0c;对标谷歌的Bert)、亚马逊 (中国AI研究生的实际导师李沐大…

正厚干货 软件测试用例设计方法之一_等价类划分

今天开始我们学习关于软件测试用例的设计方法。其中较为常用的是等价类划分发&#xff0c;那么我们就从等价类划分开始吧。一、等价类划分的介绍1.定义 把所有可能输入的数据&#xff0c;即程序的输入域划分策划国内若干部分&#xff08;子集&#xff09;&#xff0c;然后从每一…

数据处理技巧(9):MATLAB将多个矩阵放在同一行显示,并写入txt文件

MATLAB将多个矩阵放在同一行显示&#xff0c;并写入txt文件生成效果要打印的矩阵代码思路记录程序运行时间写入文档MATLAB程序生成效果相关链接记得点个赞再走~~~生成效果 将9个矩阵显示在MATLAB命令行窗口中&#xff0c;一行有3个矩阵&#xff0c;一列显示3个矩阵&#xff0c…

[附源码]JAVA毕业设计网上拍卖系统(系统+LW)

[附源码]JAVA毕业设计网上拍卖系统&#xff08;系统LW&#xff09; 项目运行 环境项配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&…

166.JWT简介与Django中使用JWT

1. JWT 1.1 JWT概述 基于django-rest-framework的登陆认证方式常用的大体可分为四种: BasicAuthentication&#xff1a;账号密码登陆验证SessionAuthentication&#xff1a;基于session机制会话验证TokenAuthentication&#xff1a; 基于令牌的验证JSONWebTokenAuthenticatio…

Python中使用国内源头下载依赖

有关更多的Python 开发内容,可访问:《 Python Flask开发指南》 Python开发中对于项目的依赖通常是用pip install命令进行下载,默认官网下载源为国外网络,会经常出现下载超时的问题。那么如何修改下载源使得我们能快速下载资源,如下介绍两种方式设置国内下载源。 国内下载源…

西湖大学张岳老师NLP课程笔记1 Introduction

西湖大学张岳老师NLP课程笔记1 Introduction 参考资料 B站链接课程主页 《Natural Language Processing: A Machine Learning Perspective 》 csdn大佬笔记 https://blog.csdn.net/qq_45645521/category_11685799.html 文章目录西湖大学张岳老师NLP课程笔记1 Introduction1.…

常用工具:介绍一款免费开源录屏工具-captura

网上能搜到的大部分录屏工具表面打着免费的旗号&#xff0c;实际上下载之后不是有水印就是限制分辨率和时长&#xff0c;介绍一款免费无水印的开源录屏截屏工具captura。 准备工作 要使用这个工具&#xff0c;必须事先在电脑上安装ffmpeg工具包&#xff0c;安装方式见&#x…

DRV8870/A4950/AT8870(3.6A单通道刷式直流电机驱动IC)

描述 AT8870是一款刷式直流电机驱动器&#xff0c;适用于打印机、电器、工业设备以及其他小型机器。两个逻辑输入控制H桥驱动器&#xff0c;该驱动器由四个N-MOS组成&#xff0c;能够以高达3.6A的峰值电流双向控制电机。利用电流衰减模式&#xff0c;可通过对输入进行脉宽调制(…

【电源专题】案例:电池存储40天电压从3.9V掉到了3.5V是什么异常?

本案例是在我休假过程中发现的。同事反馈说客户发现我们的一批产品有概率在存储40多天后发现电池从3.9V掉到了3.5V,并且制程、软件、硬件都有差异。会有可能存在什么异常? 首先我们要了解的是大多数带电池的产品在销售给客户时都会充好电(如手机/充电宝等),但不一定是充…

极市直播预告丨阿里达摩院:兼顾速度与精度的高效目标检测框架DAMO-YOLO

|极市线上分享第106期 | 一直以来&#xff0c;为让大家更好地了解学界业界优秀的论文和工作&#xff0c;极市已邀请了超过100位技术大咖嘉宾&#xff0c;并完成了105期极市线上直播分享。往期分享请前往http://bbs.cvmart.net/topics/149或直接阅读原文&#xff0c;也欢迎各位…

初学者如何学习FPGA?一文为你讲解清楚

想学习一门技术之前&#xff0c;我们先会从编程语言入手。就像学习FPGA&#xff0c;往往是从VHDL或者Verilog开始入手学习的。 当然&#xff0c;任何编程语言的学习都不能一劳永逸&#xff0c;因为任何经验技巧都是在实践的过程中才能学到&#xff0c;FPGA的学习当然也不例外。…

Python爬虫实战,Request+urllib模块,批量下载爬取飙歌榜所有音乐文件

前言 今天给大家介绍的是Python爬取飙歌榜所有音频数据并保存本地&#xff0c;在这里给需要的小伙伴们代码&#xff0c;并且给出一点小心得。 首先是爬取之前应该尽可能伪装成浏览器而不被识别出来是爬虫&#xff0c;基本的是加请求头&#xff0c;但是这样的纯文 本数据爬取…

C语言实现三子棋(超详解版本)

&#x1f680;write in front&#x1f680; &#x1f4dd;个人主页&#xff1a;认真写博客的夏目浅石. &#x1f381;欢迎各位→点赞&#x1f44d; 收藏⭐️ 留言&#x1f4dd;​ &#x1f4e3;系列专栏&#xff1a;鹏哥带我学c带我飞 &#x1f4ac;总结&#xff1a;希望你看…

分布式电源接入对配电网影响的研究附Matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;修心和技术同步精进&#xff0c;matlab项目合作可私信。 &#x1f34e;个人主页&#xff1a;Matlab科研工作室 &#x1f34a;个人信条&#xff1a;格物致知。 更多Matlab仿真内容点击&#x1f447; 智能优化算法 …

springboot+easyexcel:导入excel表格

目录 前言 1.常规导入 2.读取到指定的列 3.读取全部的sheet页 4.日期、数字及其他自定义格式的转换 5.表头有多行的读取 前言 excel表格的导入与导出&#xff0c;可以说是业务系统里比较常见的功能了&#xff0c;早些时候相信很多人都是使用POI实现excel的导入与导出功能…

还有13天圣诞节,用python整个简易版的圣诞树玩一下.......

人生苦短 我用python 好像很久没发文章啦&#xff01; 看一眼日历快到圣诞节了 &#xff0c; 现在就来用python整个圣诞树玩一下吧&#xff01; 代码&#x1f386; 模块 源码、资料电子书点击此处 import turtle as t from turtle import * import random as r import time…

项目经理的需求常见分类总结

今天聊聊如何进行需求分类、需求规划和优先级排序。我们都会面临需求多&#xff0c;任务重&#xff0c;资源少的现状&#xff0c;在这种情况下&#xff0c;就需要产品人员对产品需求进行评估&#xff0c;找到在当前阶段最重要的功能进行开发&#xff0c;那么怎么来进行评估和判…

Spring整合Apollo的原理

Spring和Apollo源码涉及的类 Spring&#xff1a;ApplicationContextInitializer、BeanFactoryPostProcessor、BeanPostProcessor、Environment、CompositePropertySource Apollo&#xff1a;ApolloApplicationContextInitializer、PropertySourcesProcessor、ApolloProcessor、…

消息发布确认

描述&#xff1a;在消息投递的过程中可能会存在消息丢失的行为产生&#xff0c;生产者到交换机&#xff0c;交换机到队列的过程都有可能出现这个现象。所以我们要有个发布确认的操作来防止消息丢西。 确认机制方案&#xff1a; 配置文件配置交换机发布确认模式&#xff1a; p…