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

【SpringBoot】使用IDEA创建SpringBoot项目

1、使用SpringBoot脚手架创建

我们使用SpringBoot的脚手架Spring Initializr创建,如图所示:
在这里插入图片描述

2、选择SpringBoot版本

最开始做项目时候,组长说创建一个 springboot 2.5.4 的项目,mysql使用 5.6.X ,maven使用是3.6.X。其实最开始我也没有多想,直接照做了,但是后面回想自己平时看到的SpringBoot开源代码,有的是使用的是2.5.X,有的是使用2.6.X,还有的是使用2.7.X版本的,除了3以上版本在实际开发中没有见过,目前2版本的见到的太多版本号不一样的了。难道只要是2版本,都可以随意使用?当然我们知道不同的版本肯定是有差异的,每个版本都存在一些bug,后面的版本会对前一个版本进行修护和升级,也有一些方法,规则的调整。

所以说,如果要是一个人开发,只要你不用到每个框架版本的新特性,使用一些常规的操作,其实也不用太关注版本,但是实际情况是,往往后端不是你一个人在开发,要是每个人版本都不一样,万一出现了什么bug,排查起来也会比统一版本的情况下排查减少很多不必要的麻烦。所以开发中项目指定版本这里存在两个目的,一个是:统一版本,方便管理(跟每家公司有自己的代码规约一样,遵守就行了),第二个目的,降低风险,不使用版本太高的框架,且往往使用常用的框架版本进行开发,开发环境也比较熟悉。当然最后还有一个,多看看官网,多了解一些框架的不同版本特性,也有助于自己开发。

2.1 推荐选择2.7.x版本开发

spring2.X版本在2023年11月24日停止维护了,因此创建spring项目时不再有2.X版本的选项,只能从3.1.X版本开始选择而Spring3.X版本不支持JDK8,JDK11,最低支持JDK17,因此JDK8也无法选择了,如图所示:
在这里插入图片描述
当然,停止维护只代表我们无法用idea主动创建spring2.X版本的项目了,不代表我们无法使用。目前阿里云还是支持创建Spring2.X版本的项目的,修改Server URL为https://start.aliyun.com,如图所示:
在这里插入图片描述

现在可以创建项目了,如图所示:
在这里插入图片描述

点击Next,建议选择2.7.x版本,并且根据项目需求添加依赖如图所示:
在这里插入图片描述
常用的依赖说明一下:

  • Lombok : 需要我们先安装Lombok插件,可以简化实体类书写;
  • String Web:添加项目的web支持,比如内置的Tomcat等;
  • MySQL Driver:我们用到MySQL数据库,所以添加MySQL相关驱动
  • MyBatis Framework:我们用到MyBatis这一ORM框架操作数据库;
  • JDBC API:Spring对JDBC的封装,如JdbcTemplate。

至此,简单的SpringBoot项目算创建完成了。

3、配置项目并启动项目

3.1 创建项目结构

1、创建配置文件
项目刚创建完成时,默认的配置文件是application.properties文件,当然我们也可以创建application.yml文件。如果在yml文件中没有输入提示,需要到设置File Types中检查是否设置了ymal文件,如图所示:
在这里插入图片描述
2、创建项目结构
在这里插入图片描述
3、配置maven
在这里配置本地Maven本地路径、Maven仓库。在本地Maven的settings.xml中会配置maven的镜像资源等信息。
在这里插入图片描述
4、检查pom.xml文件
特别强调,检查一下pom.xml的中的是否为true,有些情况会默认为true。我们需要将其设置为false,或者去掉该标签,否则在打包的时候会没有程序的入口类mainClass,然后导致无法启动程序:
在这里插入图片描述

4、 下载相关依赖
在这里我们下载之前配置好的依赖,一般项目创建后会默认下载
在这里插入图片描述
5、 配置基础内容
在配置文件中配置一些基本的内容:

server:port: 8080  # 端口号servlet:context-path: /myspringboot001   #项目根路径(前面必须加/)spring:# 项目名称application:name: my-spring-boot001# Mysql配置datasource:driver-class-name:  com.mysql.cj.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3307/my-springboot-001?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8username: rootpassword: root1998# Mybatis配置
mybatis:mapper-locations: classpath:mappers/*.xml #指定Mybatis的Mapper文件type-aliases-package: com.example.myspringboot001.*.entity  #指定Mybatis的实体目录

6、 配置Mybatis包扫描路径
我们在启动类上配置Mybatis的包扫描路径,用注解@MapperScan

@SpringBootApplication
@MapperScan(value = {"com.example.myspringboot001.**.mapper"})
public class MySpringboot001Application {public static void main(String[] args) {SpringApplication.run(MySpringboot001Application.class, args);}}

以上配置好之后,我们就可以启动springboot项目。浏览器输入:http://localhost:8080/myspringboot001/ 后出现如下内容,说明项目启动成功,如图所示:
在这里插入图片描述

4、配置多环境

在实际开发中,我们一般都会有好几套运行环境。比如开发环境、测试环境、生产环境等等
我们不可能每次都去修改一个配置文件,这就显得很麻烦。下面我们主要说一说怎么配置多环境。

1、 修改application.yml配置文件

spring:# 项目名称application:name: my-spring-boot001# 当前配置文件profiles:active: dev

2、创建多环境配置文件
在这里插入图片描述
上面的配置,项目在启动的时候就会加载application.yml(主)和application-dev.yml(副)配置文件。

注意:如果主配置文件和副配置文件的配置项冲突的时候,会优先使用副配置文件的配置项。

5、连接数据库查询数据

5.1 新建数据库my-springboot-001并且创建sys_user表
DROP TABLE IF EXISTS `sys_user`;
CREATE TABLE `sys_user`  (`id` int(0) NOT NULL AUTO_INCREMENT COMMENT '主键id',`username` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '用户名',`nickname` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户昵称',`password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户密码',`sex` enum('1','2') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户性别',`birthday` date NULL DEFAULT NULL COMMENT '用户生日',`email` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户邮箱',`phone` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户电话',`addr` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户地址',`stop_flag` enum('1','0') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户启用标志',`create_time` datetime(0) NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '用户创建时间',`update_time` datetime(0) NULL DEFAULT NULL COMMENT '用户更新时间',PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;INSERT INTO `sys_user` VALUES (1, 'xiezhr', '程序员小凡', '12345678', '1', '1999-09-19', 'xiezhr@qq.com', '13288888888', '云南省昆明市', '0', '2023-09-04 21:08:32', NULL);
INSERT INTO `sys_user` VALUES (2, 'xiaoqi', '程序员晓柒', '123456', '1', '2020-10-04', 'xiaoqi@163.com', '13288888888', '云南文山', '0', '2023-09-04 21:09:42', NULL);
INSERT INTO `sys_user` VALUES (3, 'xiaodeng', '财务小邓', '123456', '2', '2019-09-04', 'xiaodeng@qq.com', '13588888888', '云南文山', '0', '2023-09-04 21:10:43', NULL);

执行结果如图所示:
在这里插入图片描述

5.2 创建实体类
@Data
public class SysUser implements Serializable {private static final long serialVersionUID = 123456789L;/*** 主键id*/private Integer id;/*** 用户名*/private String username;/*** 用户昵称*/private String nickname;/*** 用户密码*/private String password;/*** 用户性别*/private String sex;/*** 用户生日*/private Date birthday;/*** 用户邮箱*/private String email;/*** 用户电话*/private String phone;/*** 用户地址*/private String addr;/*** 用户启用标志*/private String stopFlag;/*** 用户创建时间*/private Date createTime;/*** 用户更新时间*/private Date updateTime;}
5.3 创建Mapper接口

数据访问对象,是MVC架构中负责与数据库进行交互的组件。它封装了数据库的访问操作,提供给Service层调用。Dao层通常包含一系列方法,用于对数据库进行增删改查操作,以及与数据库的连接、事务管理等。@Mapper表示这个接口是一个MyBatis的Mapper接口,用于定义数据库操作的方法。

@Mapper
public interface SysUserMapper {/*** 查询所有用户信息* @return  所有用户信息*/List<SysUser> querySysUserList();
}
5.4 创建Mybatis的xml文件

MyBatis的映射文件(mapper),用于操作数据库中的sys_user表。其中定义了一个resultMap用于映射查询结果到SysUser对象,还定义了一个select语句用于查询sys_user表中的所有用户信息。 id=“querySyserList” 必须与mapper接口中方法名一致。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.myspringboot001.system.mapper.SysUserMapper"><resultMap type="com.example.myspringboot001.system.entity.SysUser" id="SysUserMap"><result property="id" column="id" jdbcType="INTEGER"/><result property="username" column="username" jdbcType="VARCHAR"/><result property="nickname" column="nickname" jdbcType="VARCHAR"/><result property="password" column="password" jdbcType="VARCHAR"/><result property="sex" column="sex" jdbcType="VARCHAR"/><result property="birthday" column="birthday" jdbcType="TIMESTAMP"/><result property="email" column="email" jdbcType="VARCHAR"/><result property="phone" column="phone" jdbcType="VARCHAR"/><result property="addr" column="addr" jdbcType="VARCHAR"/><result property="stopFlag" column="stop_flag" jdbcType="VARCHAR"/><result property="createTime" column="create_time" jdbcType="TIMESTAMP"/><result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/></resultMap><!--查询所有用户信息--><select id="querySysUserList" resultMap="SysUserMap">select * from sys_user</select>
</mapper>

这里需要注意的是,IDEA在创建Mybatis的Mapper XML文件时,是没有头部信息,往往我们需要去复制过来,这就会很麻烦,我们可以自定义Mybatis Mapper XML文件模板,这样我们创建Mapper XML时就会有头部信息了如图所示:
在这里插入图片描述
然后我们在新建文件时选择Mybatis Mapper XML就可以了,如图:
在这里插入图片描述

5.5 创建Service接口及实现类

Service是MVC架构中负责处理业务逻辑的组件。它封装了业务逻辑的实现细节,提供给Controller调用。Service层通常包含一系列方法,用于处理各种业务需求,如数据处理、事务管理、业务规则校验等。

1、创建SysUserService接口

public interface SysUserService {/*** 查询所有用户信息* @return  所有用户信息*/List<SysUser> querySysUserList();
}

2、创建SysUserServiceImpl实现类

@Service
public class SysUserServiceImpl implements SysUserService {@Resourceprivate SysUserMapper userMapper;@Overridepublic List<SysUser> querySysUserList() {return userMapper.querySysUserList();}
}
5.6 创建Controller

Controller是MVC架构中负责接收用户请求并处理的组件。它接收来自用户的请求,并根据请求的内容调用相应的Service方法进行业务处理,然后返回结果给用户。Controller通常负责路由请求、参数验证、调用Service等操作。

1、创建SysUserController

@RestController
@RequestMapping("/sysUser")
public class SysUserController {@Autowiredprivate SysUserService sysUserService;/*** 查询所有用户信息* @return*/@RequestMapping(value = "/querySysUser",method = RequestMethod.GET)public List<SysUser> querySysUser(){return sysUserService.querySysUserList();}
}

到此我们三大组件的代码都写完了,接下来我们来看看我们写好的接口,PostMan地址栏输入:http://localhost:8080/myspringboot001/sysUser/querySysUser,如图所示:
在这里插入图片描述
我们可以看到返回的时间格式是"2020-10-03T16:00:00.000+00:00"这样的,可读性很差。其实呢,日期格式化非常简单,我们只需要在之前定义好的实体类SysUser的日期属性上加上一个注解**@JsonFormat**即可:

import com.fasterxml.jackson.annotation.JsonFormat;@JsonFormat(pattern = "yyyy-MM-dd")
private Date birthday;

我们来测试一下,通过格式化的日期就是我们习惯的日期格式了,如图所示:
在这里插入图片描述

6、封装统一结果返回

为了保证所有接口返回的数据格式一致,减少重复代码编写。我们将对返回结果进行统一处理。
具体返回结果格式如下:

{"code": 200, // 状态码,表示请求的处理结果"message": "请求成功", // 状态消息,对请求结果的简要描述"data": { // 数据对象,用于存储具体的返回数据"key1": "value1","key2": "value2"}
}
  • code :表示请求的处理结果,一般采用HTTP状态码或自定义的业务状态码
  • message :对请求结果的简要描述,通常是一个字符串
  • data :用于存储具体的返回数据,可以是一个对象、数组或其他类型的数据
6.1 定义 IResultCode 的接口

它位于com.example.myspringboot001.common包中,可以由不同的类来实现,实现一致且统一的结果码和消息的处理和返回:

public interface IResultCode {/*** 获取状态码* @return  状态码*/String getCode();/*** 获取状态信息* @return  状态信息*/String getMsg();
}
6.2 定义了一个枚举类 ResultCode

定义了一个枚举类 ResultCode ,它实现了 IResultCode 接口,并包含了一些常见的响应码和对应的消息:

public enum ResultCode implements IResultCode, Serializable {SUCCESS("200","成功"),NOT_FOUND("404","未找到"),INTERNAL_SERVER_ERROR("500","服务器内部错误");private String code;private String msg;ResultCode(String code, String msg){this.code = code;this.msg = msg;}@Overridepublic String getCode() {return code;}@Overridepublic String getMsg() {return msg;}
}

定义系统中常见的响应码和对应的消息,用于表示不同的业务场景或操作的执行结果每个枚举常量都包含一个 code 和一个 msg ,分别表示响应码和消息内容枚举常量包括了一些常见的响应码,如 SUCCESS 表示成功, INTERNAL_SERVER_ERROR 服务器内部错误, NOT_FOUND 表示未找到。

6.3 定义统一响应结构体

定义了一个名为 Result 的类,用于表示统一的响应结构体:

@Data
public class Result<T> implements Serializable {private static final long serialVersionUID = 1L;private String code;private String msg;private T data;public static<T>  Result<T> success() {return success(null);}public static<T>  Result<T> success(T data) {Result result = new Result<>();result.setCode(ResultCode.SUCCESS.getCode());result.setMsg(ResultCode.SUCCESS.getMsg());result.setData(data);return result;}public static <T> Result<T> error(String msg) {Result<T> result = new Result<>();result.setCode(ResultCode.ERROR.getCode());result.setMsg(ResultCode.ERROR.getMsg());return result;}
}

到此,统一响应返回我们已经封装好了,我们来改造一下Controller中的代码看看效果。

1、SysUserController未改之前:

@RequestMapping(value = "/querySysUser",method = RequestMethod.GET)
public List<SysUser> querySysUser(){return sysUserService.querySysUserList();
}

2、SysUserController未改之后:

@RequestMapping(value = "/querySysUser",method = RequestMethod.GET)
public Result querySysUser(){return Result.success(sysUserService.querySysUserList());
}

再次测试返回的数据:
在这里插入图片描述

7、定义视图对象VO

从上面的返回结果,我们会发现将密码等敏感信息返回到了前端,这是非常不可取的这时,我们就需要根据前端的需求,灵活地选择需要展示的数据字段。

7.1 定义VO

定义一个需要返回前端的VO

@Data
public class SysUserVo {/*** 用户名*/private String username;/*** 用户昵称*/private String nickname;/*** 用户性别*/private String sex;/*** 用户生日*/@JsonFormat(pattern = "yyyy-MM-dd")private Date birthday;/*** 用户邮箱*/private String email;/*** 用户电话*/private String phone;/*** 用户地址*/private String addr;
}
7.2 service改造

SysUserService改造前

/*** 查询所有用户信息* @return  所有用户信息*/List<SysUser> querySysUserList();

SysUserServiceImpl改造前

@Overridepublic List<SysUser> querySysUserList() {System.out.println(sysUserMapper);return sysUserMapper.querySysUserList();}

SysUserService改造后

/*** 查询所有用户信息* @return  所有用户信息*/List<SysUserVo> querySysUserList();

SysUserServiceImpl改造后

    @Overridepublic List<SysUserVo> querySysUserList() {List<SysUserVo> sysUserVos = new ArrayList<>();List<SysUser> sysUsers = sysUserMapper.querySysUserList();// 将po的值复制到vo中sysUsers.forEach(sysUser -> {SysUserVo vo = new SysUserVo();BeanUtils.copyProperties(sysUser, vo);sysUserVos.add(vo);});return sysUserVos;}

我们再次用postman测试,输入http://localhost:8080/myspringboot001/sysUser/querySysUser,结果如图所示:
在这里插入图片描述

8、统一异常处理

日常开发中,我们处理异常一般都会用到try-catch 、throw和throws 的方式抛出异常。这种方式不仅仅程序员处理麻烦,对用户来说也不太友好我们都希望不用写过多的重复代码处理异常,又能提升用户体验。这时候全局异常处理就显得很便捷很重要了。
Springboot对于异常的处理也做了不错的支持,它提供两个注解供我们使用。

  • @ControllerAdvice注解 :用来开启全局的异常捕获,
  • @ExceptionHandler注解:说明捕获哪些异常,对那些异常进行处理
8.1 添加自定义异常与其他异常返回结果

我们在Result 类中添加如下两个方法来处理自定义异常和其他异常返回结果:

//自定义异常返回的结果
public static <T> Result<T> bussinessErr(BusinessException e) {Result<T> result = new Result<>();result.setCode(e.getErrorCode());result.setMsg(e.getErrorMsg());result.setData(null);return result;
}
//其他异常处理方法返回的结果
public static <T> Result<T> otherErr(ResultCode resultCode) {Result<T> result = new Result<>();result.setCode(resultCode.getCode());result.setMsg(resultCode.getMsg());result.setData(null);return result;
}
8.2 自定义异常类

在com.example.myspringboot001.common.exception包中新建BusinessException异常类:

public class BusinessException  extends RuntimeException{private String errorCode;private String errorMsg;public BusinessException() { }public BusinessException(String errorCode, String errorMsg) {this.errorCode = errorCode;this.errorMsg = errorMsg;}public String getErrorCode() {return errorCode;}public void setErrorCode(String errorCode) {this.errorCode = errorCode;}public String getErrorMsg() {return errorMsg;}public void setErrorMsg(String errorMsg) {this.errorMsg = errorMsg;}}
8.3 全局异常处理

我们自定义一个全局异常处理类,来处理各种异常,包括自己定义的异常和内部异常 。这样可以简化不少代码,不用自己对每个异常都使用try,catch的方式来实现。
在com.example.myspringboot001.common.handler包中新建GlobalExceptionHandler全局异常处理类:

@RestControllerAdvice
public class GlobalExceptionHandler {/*** 处理自定义异常**/@ExceptionHandler(value = BusinessException.class)@ResponseBodypublic<T> Result<T> bizExceptionHandler(BusinessException e) {return Result.bussinessErr(e);}/*** 处理其他异常**/@ExceptionHandler(value = Exception.class)@ResponseBodypublic Result exceptionHandler(Exception e) {return Result.otherErr(ResultCode.ERROR);}}
8.4 测试异常处理

我们在SysUserController 中添加如下代码来测试下异常,看看能不能捕获到:

	@RequestMapping("/getBusinessException")public Result DeException(){throw new BusinessException("400","我出错了");}@RequestMapping("/getException")public Result Exception(){Result result = new Result();int a = 1 / 0;return result;}

在这里插入图片描述
在这里插入图片描述

9、 添加系统日志

日志记录应用程序的运行状态,通过日志开发者可以更好的了解应用程序的运行情况当系统出现bug时,也能通过日志快速定位问题和解决问题。

9.1 常用日志框架

在这里插入图片描述
我们需要需要选择一个日志门面 和日志实现,Spring Boot默认集成了SLF4j 和Logback作为日志实现框架。如果您使用Maven构建项目,通常无需手动添加Logback依赖,因为Spring Boot的起步依赖(starter dependencies)中已经包含了它。

9.2 日志常用配置

1、日志输出分析,如图所示:
在这里插入图片描述

  • 日期时间:精确到毫秒
  • 日志级别:TRACE | DEBUG | INFO | WARN | ERR
  • 进程ID:60236
  • 分隔符:默认以—进行分割
  • 线程名:由中括号括起来,如[ main]
  • Logger名: 一般使用类全限定名
  • 日志内容

2、日志级别
日志级别由低到高如下

TRACE < DEBUG< INFO< WARN < ERROR

如果设置为 WARN ,则低于 WARN 的信息都不会输出 Spring Boot中默认配置是INFO级别。

3、调整日志级别
可以在配置文件application.yml中设置:

logging.level.root=DEBUG

或者在运行Spring Boot应用程序时,通过命令行参数来设置日志级别

java -jar your-application.jar --logging.level.root=DEBUG

4、日志写到文件中
需在application.properties或application.yml配置文件中设置logging.file.pathlogging.file.name属性。

logging:file:path: /myspringboot/log   # 只能指定路径,文件名默认为 spring.log,这里相当于window的 E:myspringbootlogspring.log#name: /myspringboot/log/my.log # 可以指定文件路径和文件名,这里相当于window的 E:myspringbootlogmy.log#name: my.log  使用相对路径,这里相当于window的 E:WorkPlaceIDEAmy-springboot-001my.log

注意:logging.file.path和logging.file.name只能生效一个,在配置了两者的情况下,以logging.file.name的配置为准。

9.3 日志的基本使用

1、使用官方例子

 Logger logger = LoggerFactory.getLogger(SysUserController.class);@Autowiredprivate SysUserService sysUserService;/*** 查询所有用户信息* @return*/@RequestMapping(value = "/querySysUser",method = RequestMethod.GET)public Result querySysUser(){String name = "tanya";logger.info("this name is {}", name);return Result.success(sysUserService.querySysUserList());}

2、使用lombok插件
第一种方法中,每次使用都要创建了一个名为 logger 的Logger对象,使用起来有点繁琐。这里我们引入注解方式实现。使用注解**@Slf4j** 需要安装lombok插件。

@Slf4j
public class SysUserController {@Autowiredprivate SysUserService sysUserService;/*** 查询所有用户信息* @return*/@RequestMapping(value = "/querySysUser",method = RequestMethod.GET)public Result querySysUser(){log.info("this name is {}", name);return Result.success(sysUserService.querySysUserList());}
}

可以用{} 占位符来拼接字符串,而不需要使用+来连接字符串。

9.4 日志高级配置

前面几节说的都是springboot基本日志配置,如果这些都不能满足我们的需求,我们就需要添加logback-spring.xml 官方推荐的配置文件进行配置。

注意:如果同时存在logback.xmllogback-spring.xml,Spring Boot 将会优先选择 logback-spring.xml 作为日志配置。logback.xml多用于非springboot项目;logback-spring.xml只能用于springboot项目,即带有@SpringBootApplication启动程序中才生效,在main或者Junit中依然不生效。并且这两个文件的配置项优先于application.yml的日志配置。

logback-spring.xml 中 配置了两个 分别是

  • 输出到控制台

  • 将日志写到文件中

  • 使用 指定开发/生产环境配置
    参考如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <!-- SpringBoot默认logback的配置 -->
    <include resource="org/springframework/boot/logging/logback/defaults.xml"/><springProperty scope="context" name="APP_NAME" source="spring.application.name"/>
    <property name="LOG_HOME" value="/logs/${APP_NAME}"/><!--1. 输出到控制台-->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"><!-- <withJansi>true</withJansi>--><!--此日志appender是为开发使用,只配置最低级别,控制台输出的日志级别是大于或等于此级别的日志信息--><filter class="ch.qos.logback.classic.filter.ThresholdFilter"><level>DEBUG</level></filter><encoder><Pattern>${CONSOLE_LOG_PATTERN}</Pattern><charset>UTF-8</charset></encoder>
    </appender><!-- 2. 输出到文件  -->
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"><!-- 当前记录的日志文档完整路径 --><file>${LOG_HOME}/log.log</file><!--日志文档输出格式--><encoder><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} -%5level ---[%15.15thread] %-40.40logger{39} : %msg%n%n</pattern><charset>UTF-8</charset> <!-- 此处设置字符集 --></encoder><!-- 日志记录器的滚动策略,按日期,按大小记录 --><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><fileNamePattern>${LOG_HOME}/%d{yyyy-MM-dd}.%i.log</fileNamePattern>   <!--这里是超出大小后新建的文件名,并且保存的是分割前面的旧日志,新日志还是在log.log中--><timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"><maxFileSize>5KB</maxFileSize></timeBasedFileNamingAndTriggeringPolicy><!--日志文档保留天数--><maxHistory>15</maxHistory></rollingPolicy><!-- 临界值过滤器,输出大于INFO级别日志 --><filter class="ch.qos.logback.classic.filter.ThresholdFilter"><level>INFO</level></filter>
    </appender><!-- 开发环境输出至控制台和文件 -->
    <springProfile name="dev"><root level="INFO"><appender-ref ref="CONSOLE"/><appender-ref ref="FILE"/></root>
    </springProfile><!-- 生产环境输出至控制台和文件 -->
    <springProfile name="prod"><root level="INFO"><appender-ref ref="CONSOLE"/><appender-ref ref="FILE"/></root>
    </springProfile>
    

最终完整的项目结构如下:
在这里插入图片描述

相关文章:

【SpringBoot】使用IDEA创建SpringBoot项目

1、使用SpringBoot脚手架创建 我们使用SpringBoot的脚手架Spring Initializr创建&#xff0c;如图所示&#xff1a; 2、选择SpringBoot版本 最开始做项目时候&#xff0c;组长说创建一个 springboot 2.5.4 的项目&#xff0c;mysql使用 5.6.X &#xff0c;maven使用是3.6.X…...

C++设计模式(原型、代理、适配器、组合)

一、原型模式 1.定义 用原型实例指定创建对象的种类&#xff0c;并且通过拷贝这些原型创建新的对象。 原型模式允许通过复制现有的对象来创建新对象&#xff0c;而不是通过实例化类来创建。这种方式可以避免创建重复的对象&#xff0c;从而提高性能和降低内存消耗。 2.组成 …...

如何在CentOS 7上使用FreeIPA设置集中式Linux身份验证

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 简介 FreeIPA 是一个针对 Linux 的开源安全解决方案&#xff0c;提供帐户管理和集中式身份验证&#xff0c;类似于微软的 Active Direc…...

vue2播放视频和预览文件的组件以及使用方法

##文件预览组件 按照组件 解决展示pdf的问题 npm install pdfh5 npm install canvas2.8.0 --ignore-scripts npm install --save dommatrix npm install --save web-streams-polyfill解决excel和docx预览的问题 npm install vue-office/docx vue-demi0.14.6 npm inst…...

性能之巅:Go语言优化深度探索

引言 在Go语言中进行性能优化是一个涉及多方面的工作&#xff0c;它涵盖代码编写、编译器优化、运行时系统调优以及对应用程序的深入理解。以下是一些关键点&#xff0c;包括性能分析工具、内存管理、并发优化等方面的内容&#xff0c;并附带了简单案例源代码。 性能分析工具…...

react + antd desgin 使用form功能时upload,radio,checkbox不能回显的问题

最近使用react开发 遇到form回显的问题 &#xff0c;处理upload回显的问题&#xff0c;提示 react-refresh:160 Warning: [antd: Upload] value is not a valid prop, do you mean fileList? 查看文档后&#xff0c;在form.item 组件下有一个特殊属性 valuePropName 子节点的值…...

【08】MySQL复杂查询:子查询语句详解与示例

文章目录 一、子查询的基本概念子查询的基本结构子查询的类型 二、标量子查询示例 1&#xff1a;标量子查询示例 2&#xff1a;标量子查询与IN组合 三、多行子查询示例 1&#xff1a;多行子查询与IN示例 2&#xff1a;多行子查询与ANY 四、多列子查询示例 1&#xff1a;多列子查…...

Unity 相机旋转及角度限制

前言 由于欧拉角具有直观的可读性&#xff0c;做相机旋转时选择修改eulerAngles 来实现旋转&#xff0c;但实际效果与预期稍有不同&#xff0c;这是因为欧拉角受到万向锁&#xff08;Gimbal Lock&#xff09;的影响&#xff0c;在赋值时需要对输入的角度进行调整。 if (value…...

error=‘null‘], commandType=io.lettuce.core.RedisPublisher$SubscriptionCommand]

问题 查看java应用启动日志输出下面错误&#xff1a; errornull], commandTypeio.lettuce.core.RedisPublisher$SubscriptionCommand] Completing command LatencyMeteredCommand [typeINFO, outputStatusOutput [output# Server redis_version:4.0.14 redis_git_sha1:000…...

Golang 字符串字面量表示方法

文章目录 1.普通字符串字面量&#xff08;Double-Quoted String Literals&#xff09;2.原始字符串字面量&#xff08;Raw String Literals&#xff09;3.字节字符串字面量&#xff08;Byte Slice Literals&#xff09;4.码值表示字符串字面量Unicode 转义序列UTF8 转义序列十六…...

03_Webpack模块打包工具

03_Webpack模块打包工具 目录 知识点自测 以下哪个选项是 ECMAScript 默认导出和导入的语法&#xff1f; A&#xff1a;export 和 require B&#xff1a;module.exports {} 和 import 变量名 C&#xff1a;export default 和 import 变量名 D&#xff1a;export 和 import {…...

【目标跟踪】AntiUAV600数据集详细介绍

AntiUAV600数据集的提出是为了适应真实场景&#xff0c;即无人机可能会随时随地出现和消失。目前提出的Anti-UAV任务都只是将其看做与跟踪其他目标一样的任务&#xff0c;没有结合现实情况考虑。 论文链接&#xff1a;https://arxiv.org/pdf/2306.15767https://arxiv.org/pdf/…...

十、JavaScript的应用的习题

题目一 在网页中显示一个工作中的 “ 数字时钟 ”&#xff0c;如图所示 运行效果 代码 <!DOCTYPE html> <html><head><meta charset"utf-8"><title>动态时钟</title><style>.all{width: 660px;height: 350px;margin: 60p…...

【Spring】AOP

AOP&#xff08;Aspect Oriented Programming&#xff0c;面向切面编程&#xff09;是一种编程范式&#xff0c;用来帮助开发者更好地组织程序结构。它的主要作用是为现有功能添加增强&#xff0c;而不需要修改原始代码。这与 Spring 框架提倡的“无侵入式编程”相符&#xff0…...

三维地图,智慧城市,商业智能BI,数据可视化大屏(Cesiumjs/UE)

绘图工具 三维地图&#xff1a;Cesiumjs 建模方式&#xff1a;激光点云建模、航拍倾斜摄影建模、GIS建模、BIM建模、手工建模 建模工具&#xff1a;C4D Blender GeoBuilding ArcGIS Cesiumjs <!DOCTYPE html> <html lang"en"> <head><meta …...

鸿蒙Next通过oss上传照片到阿里云

前言 最近在写纯血鸿蒙的APP&#xff0c;需要用到oss上传照片&#xff0c;之前的客户端 Android 和 IOS 都已经实现了&#xff0c;获取的阿里云签名的上传地址是服务端实现的&#xff0c;相信大部分公司都是这样的模式&#xff0c;服务端也是调用阿里云的SDK来实现的&#xff…...

小白爬虫——selenium入门超详细教程

目录 一、selenium简介 二、环境安装 2.1、安装Selenium 2.2、浏览器驱动安装 三、基本操作 3.1、对页面进行操作 3.1.1、初始化webdriver 3.1.2、打开网页 3.1.3、页面操作 3.1.4、页面数据提取 3.1.5、关闭页面 3.1.6、综合小案例 3.2、对页面元素进行操作 3.2.…...

nlp培训重点

1. SGD梯度下降公式 当梯度大于0时&#xff0c;变小&#xff0c;往左边找梯度接近0的值。 当梯度小于0时&#xff0c;减去一个负数会变大&#xff0c;往右边找梯度接近0的值&#xff0c;此时梯度从负数到0上升 2.Adam优化器实现原理 #coding:utf8import torch import torch.n…...

什么是多模态和模态

文章目录 前言一、定义1. 模态 (Modal)2. 非模态 (Non-modal) 二、GUI中1. 模态&#xff08;Modal&#xff09;对话框2. 非模态&#xff08;Modeless&#xff09;对话框 三、模态 vs 非模态 的对比四、何时使用模态和非模态对话框&#xff1f;五、Qt 中 exec() 与 show() 的区别…...

apache中的Worker 和 Prefork 之间的区别是什么?

文章目录 内存使用稳定性兼容性适用场景 Apache中的Worker和Prefork两种工作模式在内存使用、稳定性以及兼容性等方面存在区别 内存使用 Worker&#xff1a;由于使用线程&#xff0c;内存占用较少。Prefork&#xff1a;每个进程独立运行&#xff0c;内存消耗较大。 稳定性 W…...

系统监控——分布式链路追踪系统

摘要 本文深入探讨了分布式链路追踪系统的必要性与实施细节。随着软件架构的复杂化&#xff0c;传统的日志分析方法已不足以应对问题定位的需求。文章首先解释了链路追踪的基本概念&#xff0c;如Trace和Span&#xff0c;并讨论了其基本原理。接着&#xff0c;文章介绍了SkyWa…...

【Python]深入Python日志管理:从logging到分布式日志追踪的完整指南

《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! 日志是软件开发中的核心部分,尤其在分布式系统中,日志对于调试和问题定位至关重要。本篇文章将从Python标准库的logging模块出发,逐步探讨日志管理的最佳实践,涵盖日志配置、日志分层、日志格式化等基…...

DHCP Client的工作方式

【运作方式】 一开始Client没有IP资料 DHCPDISCOVER Client发出DHCPDISCOVER广播封包&#xff08;UDP port 67&#xff09;&#xff0c;寻找DHCP Server。 DHCPOFFER Client开始监听UDP port 68 &#xff08;任何&#xff09;DHCP Server收到DHCPDISCOVER封包后&#xff…...

docker-常用应用部署dockerfile模板

文章目录 概述Springboot-Djava.security.egdfile:/dev/./urandom参数说明 vue应用部署nginx.conf配置Dockerfile 概述 本文列举了Java开发中常用如SpringBoot、Vue前端等类型的应用Docker部署所需的DockerFile Springboot FROM anapsix/alpine-java:8_server-jre_unlimited…...

Unity3D学习FPS游戏(13)玩家血量控制

玩家血量控制 血条UI玩家Canvas下的Slider血量逻辑控制 子弹攻击掉血子弹发射者的区分玩家受伤逻辑子弹碰撞检测 效果 血条UI 和之前我们前面介绍的玩家武器弹夹UI的思路是一样的&#xff0c;跟详细的细节可以参考博客Unity3D装弹和弹夹UI显示。 玩家Canvas下的Slider 之前玩…...

TDesign:Switch开关

Switch 开关 文档地址 view TDSwitch(isOn: controller.isDefault, // 默认是否开启状态trackOnColor: AppColors.mainColor,onChanged: ((bool value){controller.onTapSwitch(value);return value;}), ),controller bool isDefault true; // 是否默认 void onTapSwitch(bool…...

AI在SEO中的应用与关键词优化探讨

内容概要 在当今数字化时代&#xff0c;人工智能&#xff08;AI&#xff09;技术为搜索引擎优化&#xff08;SEO&#xff09;带来了革命性的改变。传统的SEO主要依赖于人为的经验和判断&#xff0c;而AI则通过算法分析海量数据&#xff0c;提供更加精准和高效的方式优化关键词…...

[docker中首次配置git环境与时间同步问题]

11月没写东西&#xff0c;12月初赶紧水一篇。 刚开始搭建docker服务器时&#xff0c;网上找一堆指令配置好git后&#xff0c;再次新建容器后忘记怎么配了&#xff0c;&#xff0c;这次记录下。 一、git ssh指令法&#xff0c;该方法不用每次提交时输入密码 前期准备&#xff0…...

使用lumerical脚本语言创建绘制波导并进行数据分析(纯代码实现)(1)

使用lumerical脚本语言创建绘制波导、配置二维模式求解器、计算模式轮廓、计算有效折射率(neff)和群折射率(ng)随波长的变化关系、计算有效折射率(neff)随波导宽度的变化关系及针对有效折射率法进行相关数据处理(代码均有注释详解)。 一、绘制波导结构 1.1 代码实现 w…...

redis.conf

tracking-table-max-keys tracking-table-max-keys 是 Redis 中的一个配置选项&#xff0c;它与 Key Tracking 功能有关。Key Tracking 是 Redis 6.0 引入的一项功能&#xff0c;用于追踪哪些键在被客户端操作时发生了变化。 tracking-table-max-keys 的作用&#xff1a; 该配置…...