github编辑

Day1-Springboot项目初始化与配置

在本项目中使用的开发环境:

  • JDK 1.8 版本(此版本是目前企业中使用最广泛的);

  • Springboot 2.6.3 版本

  • MySQL 5.7 版本 (或者 8.x 版本都可以,本项目使用的是 5.7 版本);

  • Maven 3.8 版本 (项目构建工具);

多模块项目的起始

博客使用多模块结构进行编写,对于多模块项目,父目录和每个子目录都存在pom.xml文件,父目录下用于定义一些公用的插件和依赖管理,而子目录可以细分各个功能模块,并且按需加载插件与依赖

项目结构说明

该项目是一个多模块的 Maven 项目,主要包括以下模块以及文件:

  • weblog-springboot: 父项目,定义了所有公共的依赖和插件管理,与多模块的结构。

  • weblog-web: 前端展示模块,负责博客前台展示相关功能。

  • weblog-module-admin: 管理后台模块。

  • weblog-module-common: 公共模块,提供通用功能。

  • .gitignore: 用于指定 Git 需要忽略的文件和目录。

目录结构

项目配置

项目初始化

所有模块通过 Spring Initializr 进行初始化,在IDEA中新建项目中有内置的 Spring Initializr 支持初始化,可以直接使用

步骤如下:

  • ①:选择 Spring Boot 项目初始化器;

  • ②:填写父项目名称;

  • ③:选择新建项目所在的位置;

  • ④:选择通过 Maven 来构建项目;

  • ⑤:填写 Group 组织名称,通常为域名倒写,例如我的项目中为 cn.dogalist

  • ⑥:选择前面小节中已经安装好的 JDK 1.8 版本;

  • ⑦:选择 Java 版本,和 JDK 版本保持一致,选择 8;

注意:IDEA 通过 Spring Initializr 来创建 Spring Boot 项目,新版本不支持勾选 Java 8 了 , 可以将初始化链接换成阿里云的 http://start.aliyun.com, 就可以正常选择 Java 8 了:

按照以上步骤初始化weblog-springboot文件夹后,再建立子模块weblog-webweblog-module-commonweblog-module-admin,删除其中的无用文件夹,得到如下文件结构:

模块配置

weblog-springboot(根目录)

  • pom.xml

weblog-web

  • 模块依赖:

    ​ 勾选上 LombokSpring Web 依赖

  • pom.xml

weblog-module-admin

  • pom.xml

weblog-module-common

  • pom.xml

AOP和日志模块整合

实现自定义注解

Java 注解是从 Java 5 开始引入的,它为我们提供了一种元编程的方法,允许我们在不改变代码逻辑的情况下为代码添加元数据。这些元数据可以在编译时或运行时通过反射被访问。而自定义注解是用户定义的,用于为代码提供元数据的注解。

weblog-module-common 通用模块下,新建一个名为 aspect 的包,用于放置切面相关的功能类,接着,在其中创建一个名为 ApiOperationLog 的自定义注解:

  • @Retention(RetentionPolicy.RUNTIME): 这个元注解用于指定注解的保留策略,即注解在何时生效。RetentionPolicy.RUNTIME 表示该注解将在运行时保留

  • @Target({ElementType.METHOD}): 这个元注解用于指定注解的目标元素,即可以在哪些地方使用这个注解。ElementType.METHOD 表示该注解只能用于方法上

  • @Documented:使用 @Documented,表示在生成文档时,被注解的元素及其注解信息会被包含在文档中

什么是AOP

AOP(Aspect-Oriented Programming,面向切面编程)是一个编程范式,它提供了一种能力,让开发者能够模块化跨多个对象的横切关注点(例如日志、事务管理、安全等)。

主要概念包括:

  • 切点 (Pointcuts): 定义在哪里应用切面(即在哪里插入横切关注点的代码)。

  • 通知 (Advices): 定义在特定切点上要执行的代码。常见的通知类型有:前置通知、后置通知、环绕通知等。

  • 切面 (Aspects): 切面将切点和通知结合起来,定义了在何处和何时应用特定的逻辑。

在面向切面编程(AOP)中,Pointcut是一个核心概念,它定义了程序执行过程中的哪些点(如方法调用、异常抛出等)是我们关注的。简单来说,Pointcut就是指定了我们希望在哪些地方应用切面(Aspect)。切面包含了前置通知(Before Advice)、后置通知(After Advice)、环绕通知(Around Advice)等。

aspectj 相关注解的作用:

  • @Aspect:声明该类为一个切面类

  • @Pointcut:定义一个切点,后面跟随一个表达式,表达式可以定义为切某个注解,也可以切某个 package 下的方法

切点定义好后,就是围绕这个切点做文章了:

  • @Before: 在切点之前,织入相关代码

  • @After: 在切点之后,织入相关代码;

  • @AfterReturning: 在切点返回内容后,织入相关代码,一般用于对返回值做些加工处理的场景;

  • @AfterThrowing: 用来处理当织入的代码抛出异常后的逻辑处理;

  • @Around: 环绕,可以在切入点前后织入代码,并且可以自由的控制何时执行切点;

Pointcut的基本概念和用法

  • 静态Pointcut:基于类的结构信息来决定是否应用切面,例如所有公共方法、特定包下的所有类等。

  • 动态Pointcut:不仅依赖于静态结构信息,还可能依赖于运行时的信息,比如方法的参数值等。

在Spring框架中使用Pointcut

Spring AOP使用了AspectJ的切点表达式语言,但只支持AspectJ的一部分功能。以下是一些常用的Pointcut表达式示例:

  1. 匹配特定的方法签名

    这个例子表示,在com.example.service.MyService类中的任何公共方法执行之前,都会先执行beforeMethod方法。

  2. 匹配特定的参数

    这里,只有当find*方法的参数为name时,才会触发beforeFindByName方法。

  3. 匹配特定的异常

    MyService中的任意方法抛出异常时,会执行afterThrowing方法。

  4. 匹配多个条件

    可以使用逻辑运算符&&(与)、||(或)、!(非)组合多个Pointcut条件。

    这个例子表示除了MyService的子类之外的所有MyService方法执行前都会调用beforeMethodExceptSubclasses

创建自定义Pointcut

如果标准的Pointcut表达式不能满足需求,还可以创建自定义的Pointcut。这通常涉及到实现Spring的org.aspectj.lang.annotation.Pointcut注解,并定义自己的逻辑来确定何时应该应用切面。

这里,myServiceMethods是一个自定义的Pointcut,它定义了所有MyService类的方法。然后,beforeMyServiceMethods会在这些方法执行前被调用。

使用AOP添加日志逻辑

在我们的项目中,使用AOP,我们可以为所有使用 @ApiOperationLog 注解的方法自动添加日志逻辑,而不需要在每个方法中手动添加。

配置日志模块Logback

Logback 是日志框架 SLF4J 的一个实现,它被设计用来替代 log4j。Logback 提供了更高的性能,更丰富的日志功能和更好的配置选项。

src/main/resources 目录下,创建一个名为 logback-weblog.xml 的文件,这是Logback的配置文件。

创建 JSON 工具类

weblog-module-common 通用模块下,创建一个 utils 包,用于统一放置工具类相关,然后,新建一个名为 JsonUtil 的工具类, 代码如下:

定义日志切面类

工具类搞定后,在 aspect 包下,新建切面类 ApiOperationLogAspect

添加包扫描

在启动类 WeblogWebApplication 中,手动添加包扫描 @ComponentScan , 指定扫描 cn.dogalist.weblog 包下面的所有类:

环境区分和日志测试

文件结构

环境划分

如上面文件结构,在weblog-webresources文件下创建application.yml配置文件,application.yml中定义选择的环境

对应的激活环境配置则与application-{active}.yml配置的内容相同,可以通过定义不同的application-*.yml文件创建不同的配置,在这个项目中只定义了测试环境和生产环境

日志测试

如上面文件结构,在weblog-web 下创建controller包和model包,分别在两个包中新建类TestControllerUser

  • TestController

  • User

添加完成后,运行WeblogWebApplication文件,同时使用api测试工具发送POST请求到localhost:8080/test,携带请求参数如下:

api请求正常:

api请求

成功得到日志信息:

测试结果

最后更新于