Maven 使用手册【原创·个人私用】

Maven 是干嘛的?

通过Maven,可以帮助我们做:

  • 项目的自动构建,包括代码的编译、测试、打包、安装、部署等操作。
  • 依赖管理,项目使用到哪些依赖,可以快速完成导入。

就是我们不需要手动导入 Jar 包了,直接通过 Maven 的配置文件 pom.xml 就可以进行远程下载,然后应用于我们指定的项目。

Pom.xml

<?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">
    <!-- 定义 maven 配置文件需要的 标签元素 -->
    <modelVersion>4.0.0</modelVersion>

    <!-- 组别 => 类似于包名,但实际上我们称为项目组名,它是我们虚拟定义的 -->
    <groupId>org.example</groupId>
    <!-- 项目的名字 -->
    <artifactId>MavenTest</artifactId>
    <!-- 项目的版本号, SNAPSHOT 表示快照 => 意思是正在开发中 -->
    <version>1.0-SNAPSHOT</version>
    <!--通过将 <packaging> 元素设置为 pom,Maven 就知道该项目是一个聚合项目,不会生成任何构件,而是根据子项目的定义进行构建和管理。-->
    <!--<packaging>pom</packaging>-->

<!--    <modules>-->
<!--        <module>SonA</module>-->
<!--    </modules>-->

    <properties>
        <!--意思是 JDK 用的 1.8-->
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>
    <!--依赖、第三方库-->
    <dependencies>
        <dependency>
            <!--通过 groupId、artifactId、version 三属性(Maven 坐标来下载依赖)-->
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.22</version>
            <!--此依赖是作用域范围-->
            <scope>provided</scope>
            <!--<type>jar</type>-->
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <version>5.8.1</version>
            <scope>test</scope>
            <!--一些依赖它会导入 其它的前提依赖、但我们还不想导入它!用 exclusions -->
            <exclusions>
                <exclusion>
                    <!--比如我们不想导入 junit 携带过来的 junit-jupiter-engine -->
                    <groupId>org.junit.jupiter</groupId>
                    <artifactId>junit-jupiter-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.30</version>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.30</version>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
            <!--标记为该依赖为 可选依赖,即不会下载和导入此依赖!-->
            <!--当值为 false 才会下载和导入此依赖!-->
            <optional>true</optional>
        </dependency>
    </dependencies>
    <!--打包用到的 插件!Maven 其实也可以远程下载一些 插件 ~ -->
    <plugin>
        <artifactId>maven-assembly-plugin</artifactId>
        <version>3.1.0</version>
        <configuration>
            <descriptorRefs>
                <descriptorRef>jar-with-dependencies</descriptorRef>
            </descriptorRefs>
            <archive>
                <manifest>
                    <addClasspath>true</addClasspath>
                    <mainClass>com.test.Main</mainClass>
                </manifest>
            </archive>
        </configuration>
        <executions>
            <execution>
                <id>make-assembly</id>
                <phase>package</phase>
                <goals>
                    <goal>single</goal>
                </goals>
            </execution>
        </executions>
    </plugin>
</project>

在 Maven 中,项目的模型由一个 POM(Project Object Model)文件定义,该文件是一个 XML 文件,描述了项目的结构、依赖关系、构建配置等信息。<modelVersion> 元素指定了使用的 POM 模型的版本。

在现代的 Maven 项目中,通常使用的是 Maven 4.0.0 的模型版本。这个版本的模型定义了一套规范,用于描述 Maven 项目的基本结构和配置。通过指定 <modelVersion>4.0.0</modelVersion>,Maven 就知道使用的是这个版本的模型,从而按照相应的规范解析和处理项目的 POM 文件。

作用域讲解

我们着重来讲解一下scope属性,它决定了依赖的作用域范围:

  • compile :为默认的依赖有效范围。如果在定义依赖关系的时候,没有明确指定依赖有效范围的话,则默认采用该依赖有效范围。此种依赖,在编译、运行、测试时均有效。
  • provided :在编译、测试时有效,但是打包的时候不会打包进去!也就是说,打包的项目在运行时,可能不需要此依赖,比如我们上面的Lombok,我们只需要在编译阶段使用它,编译完成后,实际上已经转换为对应的代码了,因此Lombok也就不需要打包出去了。
  • runtime :只在运行、测试的时候有效,即运行和测试的时候才会去用这个依赖。
  • test :只在测试时有效,例如:JUnit,我们一般只会在测试阶段使用JUnit,而实际项目运行时,我们就用不到测试了,那么我们来看看,导入JUnit的依赖:
  • system:作用域和provided是一样的,但是它不是从远程仓库获取,而是直接导入本地Jar包
<dependency>
     <groupId>javax.jntm</groupId>
     <artifactId>lbwnb</artifactId>
     <version>2.0</version>
     <scope>system</scope>
     <systemPath>C://学习资料/4K高清无码/test.jar</systemPath>
</dependency>

Maven 项目资源文件

在Maven 项目中,所有的资源文件,包括配置文件都得放在 resource文件夹。比如说,mybatis.xml 就得放在 resource 文件夹下 这也是为了方便统一管理

然后只要使用 Resources.getResourceAsStream(resource文件夹下的路径即可,属于相对路径) 就可以拿到这个 文件的流

public class MainTest {

    //因为配置文件位于内部,我们需要使用Resources类的getResourceAsStream来获取内部的资源文件
    private static SqlSessionFactory factory;

    //在JUnit5中@Before被废弃,它被细分了:
    @BeforeAll // 一次性开启所有测试案例只会执行一次 (方法必须是static)
    // @BeforeEach 一次性开启所有测试案例每个案例开始之前都会执行一次
    @SneakyThrows
    public static void before(){
        factory = new SqlSessionFactoryBuilder()
                .build(Resources.getResourceAsStream("mybatis.xml"));
    }


    @DisplayName("Mybatis数据库测试")  //自定义测试名称
    @RepeatedTest(3)  //自动执行多次测试
    public void test(){
        try (SqlSession sqlSession = factory.openSession(true)){
            TestMapper testMapper = sqlSession.getMapper(TestMapper.class);
            System.out.println(testMapper.getStudentBySid(1));
        }
    }
}

上方的一些注解,是 Junit5 支持的用法。可以适当的了解一下 ~

Maven 继承

一个Maven项目可以继承自另一个Maven项目,比如多个子项目都需要父项目的依赖,我们就可以使用继承关系来快速配置。

我们右键左侧栏,新建一个模块,来创建一个子项目:

<?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">
    <!--指定它的父亲项目叫啥名、属于哪个根项目/组别-->
    <parent>
        <artifactId>MavenTest</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <!--然后只需要 指明子项目的 名字就完事了 ~ -->
    <artifactId>ChildModel</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

</project>

我们还可以让父Maven项目统一管理所有的依赖,包括版本号等,子项目可以选取需要的作为依赖,而版本全由父项目管理,我们可以将dependencies全部放入dependencyManagement节点,这样父项目就完全作为依赖统一管理。

所以说 父项目 pom.xml 就可以这样写:

<!--放到 dependencyManagement 标签中的 dependencies 依赖,就都可以管理了-->
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.22</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <version>5.8.1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.27</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.7</version>
        </dependency>
    </dependencies>
</dependencyManagement>

然后 子 pom.xml 就不会实现 不写依赖就能用了!而是必须得 写依赖的声明,当 没有写版本号 <version>

的时候,就代表这个 依赖是从 父 pom.xml <dependencyManagement> 标签内 继承过来的依赖!

<project>
    <parent>
        <!-- 父 POM 的坐标 -->
    </parent>
    
    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- 其他依赖项 -->
    </dependencies>
</project>

Maven 常用命令

我们可以看到在IDEA右上角Maven板块中,每个Maven项目都有一个生命周期,实际上这些是Maven的一些插件,每个插件都有各自的功能,比如:

  • clean命令,执行后会清理整个target文件夹,在之后编写Springboot项目时可以解决一些缓存没更新的问题。
  • validate命令可以验证项目的可用性。
  • compile命令可以将项目编译为.class文件。
  • install命令可以将当前项目安装到本地仓库,以供其他项目导入作为依赖使用
  • verify命令可以按顺序执行每个默认生命周期阶段(validatecompilepackage等)

Maven 测试项目

通过使用test命令,可以一键测试所有位于test目录下的测试案例,请注意有以下要求:

  • 测试类的名称必须是以Test结尾,比如MainTest
  • 测试方法上必须标注@Test注解,实测@RepeatedTest无效

这是由于JUnit5比较新,我们需要重新配置插件升级到高版本,才能完美的兼容Junit5:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <!-- JUnit 5 requires Surefire version 2.22.0 or higher -->
            <version>2.22.0</version>
        </plugin>
    </plugins>
</build>

现在@RepeatedTest@BeforeAll也能使用了。

因为@RepeatedTest@BeforeAll 都是 JUnit 5的

Maven 项目打包

在打包之前也会执行一次test命令,来保证项目能够正常运行,当测试出现问题时,打包将无法完成,我们也可以手动跳过,选择执行Maven目标来手动执行Maven命令,输入mvn package -D maven.test.skip=true 来以跳过测试的方式进行打包。或者是,直接 双击 最上方工具栏 那里的 build 命令,也可以直接进行 打包!然后你就能在 target 目录下就能看到 .jar 这个执行文件了!

  • deploy命令用于发布项目到本地仓库和远程仓库,一般情况下用不到,这里就不做讲解了。
  • site命令用于生成当前项目的发布站点,暂时不需要了解。
posted @ 2024-01-13 08:24  小哞^同^学的技术博客  阅读(4)  评论(0编辑  收藏  举报