# Maven

# 介绍

Apache Maven:项目管理和构建工具,基于项目对象模型(POM)的概念,通过一小段描述信息来管理项目的构建
mvn 中央仓库
Maven 坐标:

  • groupId:项目隶属组织名,通常为域名反写
  • artifactId:项目名称,通常为模块名
  • version:版本号
  • scope:表示作用范围
    • compile:默认,main、test 和 package 都生效
    • test:只在 test 文件夹内生效
    • provided:打包阶段不生效
    • runtime:main 文件内不生效

Maven 生命周期:

  • clean:移除上次构建生成文件
  • default:
    • compile:编译项目源代码
    • test:单元测试
    • package:将编译后的文件打包
    • install:安装项目到本地仓库
  • site:生成报告,发布站点

# 配置

修改 conf/settings.xml 的本地仓库地址和源,添加 bin 的环境变量

l
<localRepository>C:/DATA/java/maven/apache-maven-3.8.8/repository</localRepository>
<mirror>
    <id>aliyunmaven</id>
    <mirrorOf>*</mirrorOf>
    <name>阿里云公共仓库</name>
    <url>https://maven.aliyun.com/repository/public</url>
</mirror>

IDEA 全局配置
IDEA 开始界面 -> 自定义 -> 所有设置
更改 Maven 主路径和用户设置文件,并更改其他位置的 java 版本
Maven配置

# 继承与聚合

继承:子工程可以继承父工程中的配置依赖,简化依赖配置,统一依赖管理
聚合:将多个模块组织成一个整体,同时进行项目的构建打包
父工程只用来依赖配置,不进行代码编写
设置打包方式: <packaging>pom</packaging> ,父工程打包方式设置为 pom
管理公共依赖: <dependencies> ,直接引入指定的依赖版本,以子工程设置的版本优先
依赖版本锁定: <dependencyManagement> ,不直接引入依赖,管理依赖版本
自定义属性值: <properties><jwt.version>4.4.0</jwt.version></properties> 设置属性, ${jwt.version} 获取属性
添加模块: <modules><module> ,父工程添加模块名,便于后续打包
子工程继承父工程 <parent> ,并设置父工程 pom 文件相对路径 <relativePath> ,不指定会从本地和远程仓库查找

l
<?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.mof</groupId>
    <artifactId>ecomm_platform</artifactId>
    <version>1.0.0</version>
    <packaging>pom</packaging>
    <modules>
        <module>common</module>
        <module>admin</module>
    </modules>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.9.RELEASE</version>
        <relativePath/>
    </parent>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <mysql.version>5.1.47</mysql.version>
        <mybatis.version>2.1.1</mybatis.version>
        <druid.version>1.2.5</druid.version>
        <mybatis-plus.version>3.5.2</mybatis-plus.version>
    </properties>
    <!-- 相关依赖管理 -->
    <dependencyManagement>
        <dependencies>
            <!-- mysql 驱动 -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql.version}</version>
            </dependency>
            <!--mybatis-->
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>${mybatis.version}</version>
            </dependency>
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
                <version>${mybatis-plus.version}</version>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid-spring-boot-starter</artifactId>
                <version>${druid.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <!-- lombok 通用依赖引入 -->
    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>
</project>

# 私服

私服部署与设置
仓库下载顺序:本地仓库 --> 私服 maven-releases --> 私服 maven-snapshots --> 远程阿里云 maven 仓库 --> 远程中央仓库
mvn deploy 发布,将 jar 包上传到私服
maven 配置文件

l
<!-- 下载依赖 -->
<!-- 私服配置 -->
<mirrors>
    <mirror>
        <!-- 该镜像的唯一标识符。id 用来区分不同的 mirror 元素。 -->
        <id>maven-public</id>
        <!-- 镜像名称 -->
        <name>maven-public</name>
        <!--* 指的是访问任何仓库都使用我们的私服 -->
        <mirrorOf>*</mirrorOf>
        <!-- 该镜像的 URL。构建系统会优先考虑使用该 URL,而非使用默认的服务器 URL。 -->
        <url>http://192.168.60.133:8081/repository/maven-public/</url>     
    </mirror>
    <mirror>
        <id>nexus-aliyun</id>
        <name>Nexus aliyun</name>
        <mirrorOf>*</mirrorOf>
        <url>http://maven.aliyun.com/nexus/content/groups/public</url>
    </mirror>
</mirrors>
<!-- 私服下载设置,不下载 snapshots 版本 -->
<repositories>
    <repository>
        <id>maven-nexus</id>
        <url>http://localhost:8081/repository/maven-public/</url>
        <releases>
            <enabled>true</enabled>
        </releases>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
    </repository>
    <repository>
      <id>maven-aliyun</id>
      <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
      <releases>
         <enabled>true</enabled>
      </releases>
      <snapshots>
         <enabled>true</enabled>
         <updatePolicy>always</updatePolicy>
         <checksumPolicy>fail</checksumPolicy>
      </snapshots>
   </repository>
</repositories>
<!-- 下载插件 -->
<!-- 该配置是为了防止 pom 中的 jar 包从私服下载之后,但是执行 mvn 中的插件还是从中央仓库中下载 -->
<pluginRepositories>
    <pluginRepository>
        <id>maven-nexus</id>
        <name>maven-nexus</name>
        <url>http://10.172.0.201:8081/nexus/repository/maven-public/</url>
        <releases>
            <enabled>true</enabled>
        </releases>
        <snapshots>
            <enabled>true</enabled>
        </snapshots>
    </pluginRepository>
</pluginRepositories>
<!-- 发布依赖 -->
<!-- 私服账号密码 -->
<servers>
    <server>
        <id>releases</id>
        <username>admin</username>
        <password>123</password>
    </server>
    <server>
        <id>snapshots</id>
        <username>admin</username>
        <password>123</password>
    </server>
</servers>
<!-- 私服对应 url -->
<distributionManagement>
    <repository>
        <id>releases</id>
        <name>Releases</name>
        <url>http://192.168.60.133:8081/repository/maven-releases/</url>
    </repository>
    <snapshotRepository>
        <id>snapshots</id>
        <name>Snapshot</name>
        <url>http://192.168.60.133:8081/repository/maven-snapshots/</url>
    </snapshotRepository>
</distributionManagement>

# 测试

  • 单元测试:基本单位测试,白盒
  • 集成测试:子系统测试,灰盒
  • 系统测试:黑盒
  • 验收测试:黑盒

JUnit:Java 测试框架,测试代码与源代码分开,自动化测试,产生测试报告

l
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter</artifactId>
    <version>5.9.1.</version>
    <scope>test</scope>
</dependency>

类名为模块名 + Test,在测试方法上添加 @Test 注解,方法修饰符为 public void
断言:确定被测试方法是否按预期效果运行

断言方法描述
Assertions.assertEquals(Object exp, object act, String msg)检查两个值是否相等,不相等就报错。
Assertions.assertNotEquals(object unexp, object act, String msg)检查两个值是否不相等,相等就报错。
Assertions.assertNull(Object act, String msg)检查对象是否为 null,不为 null 就报错。
Assertions.assertNotNull(object act, String msg)检查对象是否不为 null,为 null 就报错。
Assertions.assertTrue(boolean condition, String msg)检查条件是否为 true,不为 true 就报错。
Assertions.assertFalse(boolean condition, String msg)检查条件是否为 false,不为 false 就报错。
Assertions.assertThrows(class expType, Executable exec, string msg)检查是否抛出指定类型的异常,未抛出则报错

常见注解

注解说明备注
@Test修饰方法单元测试
@ParameterizedTest参数化测试(可以让单个测试运行多次,每次运行时仅参数不同)用了该注解,就不需要 @​Test 注解了
@ValueSource参数化测试的参数来源,赋予测试方法参数与参数化测试注解配合使用
@DisplayName指定测试类、测试方法显示的名称(默认为类名、方法名)-
@BeforeEach修饰实例方法,在每一个测试方法执行之前执行一次初始化资源(准备工作)
@AfterEach修饰实例方法,在每一个测试方法执行之后执行一次释放资源(清理工作)
@BeforeAll修饰静态方法,在所有测试方法之前只执行一次初始化资源(准备工作),static
@AfterAll修饰静态方法,在所有测试方法之后只执行一次释放资源(清理工作),static
a
public class UserServiceTest {
    @Test
    public void testGetUser(){
        UserService userService = new UserService();
        String mof = userService.getUser("mof");
        System.out.println(mof);
        // 断言
        Assertions.assertEquals("mof", mof);
    }
    // 参数化测试
    @ParameterizedTest
    @ValueSource(strings = {"mof", "fom", "ykm"})
    public void testGetUser2(String name){
        UserService userService = new UserService();
        String user = userService.getUser(name);
        System.out.println(user);
    }
}

# 日志记录

  • JUL:JavaSE 平台提供的官方日志框架,配置相对简单,但不够灵话,性能较差。
  • Log4j:一个流行的日志框架,提供了灵活的配置选项,支持多种输出目标。
  • Logback:基于 Log4j 升级而来,提供了更多的功能和配置选项,性能优于 Log4j。
  • Slf4j:Simple Logging Facade for Java,简单日志门面,提供了一套日志操作的标准接口及抽象类,允许应用程序使用不同的底层日志框架(Log4j 或 Logback)。

日志级别(由低到高)

  • trace:追踪,记录程序运行轨迹
  • debug:调试,记录程序调试过程中的信息,实际应用中一般将其视为最低级别
  • info:记录一般信息,描述程序运行的关键事件,如:网络连接、IO 操作
  • warn:警告信息,记录潜在有害的情况
  • error:错误信息

# 配置

springboot 项目自带 Logback 依赖

l
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
</dependency>

logback.xml

l
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!-- 控制台输出 -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!-- 格式化输出:% d 表示日期,% thread 表示线程名,%-5level 表示级别从左显示 5 个字符宽度,% logger 显示日志记录器的名称, % msg 表示日志消息,% n 表示换行符 -->
            <!-- 颜色:% black, % red, % green,% yellow,% blue, % magenta,% cyan, % white, % gray,% boldRed,% boldGreen, % boldYellow, % boldBlue, % boldMagenta,% boldCyan, % boldWhite,% highlight-->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS}  %highlight(%-5level) --- [%thread] %cyan(%-40logger{40}) : %msg%n</pattern>
        </encoder>
    </appender>
    <!-- 系统文件输出 -->
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!-- 日志文件输出的文件名,% i 表示序号 -->
            <FileNamePattern>D:/projects/web-ai-project/log/tlias-%d{yyyy-MM-dd}-%i.log</FileNamePattern>
            <!-- 最多保留的历史日志文件数量 -->
            <MaxHistory>30</MaxHistory>
            <!-- 最大文件大小,超过这个大小会触发滚动到新文件,默认为 10MB -->
            <maxFileSize>10MB</maxFileSize>
        </rollingPolicy>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!-- 格式化输出:% d 表示日期,% thread 表示线程名,%-5level 表示级别从左显示 5 个字符宽度,% msg 表示日志消息,% n 表示换行符 -->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS}  %-5level --- [%thread] %-40logger{40} : %msg%n</pattern>
        </encoder>
    </appender>
    <!-- 日志输出级别:TRACE,DEBUG,INFO,WARN,ERROR,ALL 或 OFF -->
    <root level="INFO">
        <appender-ref ref="STDOUT" />
        <appender-ref ref="FILE" />
    </root>
</configuration>

# 使用

a
private static final Logger log = LoggerFactory.getLogger(DeptController.class);
log.info("test");

或者直接在类上添加 lombok 的 @Slf4j 注解