跳至主要內容

Maven

TenSoFlow...大约 15 分钟项目管理工具Maven

Maven

简介

Maven是一个项目依赖管理和构建工具。传统需要去官网下载各个jar包(比如 Spring、MyBatis)然后手动导入项目。如果Jar包之间有冲突或者版本不对,非常痛苦。为了解决此问题Maven应运而生。

应用场景

依赖导入

只需要在pom.xml文件中写下几行配置坐标,Maven就会自动从中央仓库(网络)下载这些Jar包到你的指定的本地仓库(电脑磁盘),并自动处理它们之间的嵌套关系(比如 A 依赖 B,B 依赖 C,Maven 会自动把 B 和 C 都下载好)。Maven并不是每次运行都去中央仓库(网络)下载。它会先检查你指定的本地仓库(电脑磁盘)如果有则直接从本地读取,否则就去中央仓库下载。

项目构建

能够批量编译、组织文件结构、批量复制Jar包、能够打包成Jar包或者war包。

依赖共享

能够把你自己写的一些工具类上传到中央仓库,供同事或者全世界开发者使用。

工作原理模型图

Maven核心工作逻辑:通过pom.xml定义项目对象模型(Project Object Model)与依赖管理模型,依赖管理会从central(中央仓库)、b2b(私有仓库)、local(本地仓库)等仓库拉取所需依赖。Maven基于生命周期的各个阶段调用不同 插件(其本质也是一个Jar包) 处理源文件、资源文件等,经编译打包等步骤生成中间产物、二进制产物及最终打包产物。从而完成项目构建流程。

Maven 下载

https://maven.apache.org/docs/history.htmlopen in new window

安装条件:Maven需要本机安装Java环境,必需包含JAVE_HOME环境变量

软件安装:解压即可(绿色免安装)

目录结构:

LICENSE、NOTICE、README.txt:针对Maven版本和第三方软件等简要介绍

Maven 配置环境变量

必须将Maven配置到环境变量中,不然后续使用不了mvn命令。此步骤可有可无因为IDEA中可通过点击的方式执行Maven命令。

系统变量名:MAVEN_HOME
系统变量值:D:\TenSoFlow\Code\Maven\apache-maven-3.6.0 (bin目录所在的上级目录)

在系统变量名为PATH中加入
%MAVEN_HOME%\bin

Maven 配置文件

主要需要修改Maven的本地仓库地址(默认是C盘)、镜像网址编译项目的JDK版本。Maven安装目录的conf目录下默认会有一个settings.xml,需要在其中修改默认配置。其名称可以更改不一定非要叫settings.xml。比如电脑中有A和B两个项目。你希望其本地仓库分别存储到不同位置,则可以创建a.xml放A项目的配置创建b.xml放B项目的配置。当然xml的名称任意,不过最好不要有中文

<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
    
    <!-- 本地缓存路径,根据自己需求更改 -->
    <localRepository>D:\TenSoFlow\Code\Maven\LuoChuanRepository</localRepository>
    
    <mirrors>
        <!-- 阿里云镜像 -->
        <mirror>
            <id>aliyunmaven</id>
            <mirrorOf>*</mirrorOf>
            <name>阿里云公共仓库</name>
            <!-- 此处的url如果以https开头则可能导致下载依赖失败 -->
            <!-- 可能原因:JDK安装路径下没有导入阿里云证书 -->
            <!-- 一般和JDK版本有关,高版本JDK中的证书库中可能已经自带 -->
            <!-- JDK如何配置证书可以去看本网站《代码炼金术》这篇笔记 -->
            <!-- 如果失败且急需使用可换成http试试,最好使用https因为安全 -->
            <url>https://maven.aliyun.com/repository/public</url>
        </mirror>
    </mirrors>
    
    <!-- 统一项目的Java编译版本避免因环境差异导致的编译错误或运行时兼容问题 -->
    <profile>
        <!-- profile 唯一标识 ID,用于激活该配置时指定 -->
        <id>jdk-8</id>
        
        <!-- 激活配置 -->
        <activation>
            <!-- 默认激活该 profile -->
            <activeByDefault>true</activeByDefault>
            <!-- 当系统环境中的JDK版本为8时,自动激活该profile -->
            <jdk>8</jdk>
        </activation>

        <properties>
            <!-- 指定项目的Java源码遵循JDK8的语法规范 -->
            <maven.compiler.source>8</maven.compiler.source>
            <!-- 指定编译后生成的 class 文件兼容 JDK 8 运行环境 -->
            <maven.compiler.target>8</maven.compiler.target>
            <!-- 编译器版本:指定 Maven 使用 JDK 8 的 javac 编译器进行编译 -->
            <maven.compiler.compilerVersion>8</maven.compiler.compilerVersion>
        </properties>
    </profile>

</settings>

Maven 工程的GAVP

Maven中的GAVP指的是GroupId、ArtifactId、Version、Packaging等四个属性的缩写,其中前三个是必要的。而Packaging属性为可选项,默认打包方式为Jar。这四个属性主要为每个项目在Maven仓库中做一个标识,类似人的姓名。有了具体标识,方便后期项目之间的相互引用依赖。

GroupId:组织/公司的包结构标识
格式:通常以组织的域名反写开头主流有com和org
商业组织:com.公司名.项目组.项目(如 com.alibaba.cloud)
开源组织:org.组织名.项目(如 org.springframework.boot)

ArtifactId:项目/模块名
推荐用小写字母 + 中划线分隔 如luochuan-application

Version:版本号
格式:主版本号.次版本号.修订号 
如 1.0.1 没有严格规定可以自定义
还可添加预发布/构建信息如 1.0.0-SNAPSHOT 表示快照版、1.0.0-RC1 表示候选版

packaging:项目打包类型
jar(默认值):普通Java工程
war:Java的web工程
pom:代表不会打包而是作为继承的父工程

Maven 工程项目结构

Maven是一个强大的构建工具,它提供一种**标准化(项目结构是提交规定好的必须这么写如src目录下必须是main目录)**的项目结构。对应的代码必须写在对应的位置。

-- pom.xml                       # ✅ 固定:Maven 项目核心管理文件,Maven 必须识别该文件名
-- src                           # ✅ 固定:项目源码与资源的根目录,Maven 约定的核心目录
   |-- main                      # ✅ 固定:存放项目生产环境的核心代码和资源(与 test 对应)
   |  |-- java                   # ✅ 固定:存放 Java 源代码的目录
   |  |  `-- com/tensoflow       # 自定义:开发者根据组织/项目定义的包结构,可随意修改
   |  |     |-- controller       # 自定义:业务分层目录,可根据项目需求改名
   |  |     |-- service          # 自定义:业务分层目录,可根据项目需求改名
   |  |     |-- dao              # 自定义:业务分层目录,可根据项目需求改名
   |  |     `-- model            # 自定义:业务分层目录,可根据项目需求改名
   |  |-- resources              # ✅ 固定:存放项目生产环境配置文件、静态资源的目录
   |  |  |-- log4j.properties    # 自定义:日志配置文件,文件名可根据日志框架修改
   |  |  |-- spring-mybatis.xml  # 自定义:Spring 整合 MyBatis 配置文件,文件名可自定义
   |  |  `-- static              # 自定义:静态资源分类目录,可自定义是否创建/改名
   |  |     |-- css              # 自定义:CSS 资源分类目录,可自定义
   |  |     |-- js               # 自定义:JavaScript 资源分类目录,可自定义
   |  |     `-- images           # 自定义:图片资源分类目录,可自定义
   |  `-- webapp                 # ✅ 固定(Web 项目专属):存放 Web 应用的页面
   |     |-- WEB-INF             # ✅ 固定(Web 项目专属):存放 web 应用配置文件
   |     |  |-- web.xml          # ✅ 固定(Web 项目专属):Web 应用的部署描述文件
   |     |  `-- classes          # ✅ 固定(Web 项目专属):存放编译后的 class 文件
   |     `-- index.html          # 自定义:Web 应用入口页面,文件名可自定义
   `-- test                      # ✅ 固定:存放项目单元测试、集成测试的代码和资源
       |-- java                  # ✅ 固定:存放 Java 单元测试代码的目录
       |-- resources             # ✅ 固定:存放测试环境专属配置文件的目录

Maven 项目构建

项目构建是指将源代码、依赖库和资源文件等转换成可执行或可部署的应用程序的过程,在这个过程中包括编译源代码、链接依赖库、打包和部署等多个步骤。项目构建是软件开发过程中至关重要的一部分,能够大大提高软件开发效率,使得开发人员能够更加专注于应用程序的开发和维护,而不必关心应用程序的构建细节。常见构建工具包括Maven、Gradle、Ant等。

Maven 命令方式构建项目

在CMD中进入到pom.xml文件所在目录,mvn系列命令必须在项目的pom.xml所在目录中使用。

命令描述
mvn compile编译项目,生成target文件
mvn package打包项目,生成jar或war文件
mvn clean清理编译或打包后的项目结构
mvn install打包后上传到maven本地仓库
mvn deploy只打包,上传到maven私服仓库
mvn site生成站点
mvn test执行测试源码

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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <!-- Maven 模型版本 固定值为 4.0.0 (Maven 3.x 及以上版本均使用该模型版本) -->
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.luochuan</groupId>
    <artifactId>luochuan</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    
    <name>luochuan</name>
    <description>luochuan框架</description>

    <!-- 统一管理依赖版本,可自定义值,供dependency中的version引用 -->
    <properties>
        <!-- Lombok版本 -->
        <lombok.version>1.18.20</lombok.version>
        <!-- 日志实现版本 -->
        <logback.version>1.2.12</logback.version>
        <!-- junit版本 -->
        <junit.version>4.13.2</junit.version>
    </properties>

    <dependencies>
        
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <!-- ${junit.version}对应4.13.2 -->
            <version>${junit.version}</version>
            <!-- 依赖范围 -->
            <scope>test</scope>
        </dependency>
        
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <!-- ${lombok.version}对应1.18.20 -->
            <version>${lombok.version}</version>
        </dependency>

        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <!-- ${logback.version}对应1.2.12 -->
            <version>${logback.version}</version>
        </dependency>
    </dependencies>
    
    <build>
        <!-- 
        	finalName标签:指定项目打包后的最终文件名(不含后缀)
            若不配置此标签,默认打包名称为:${artifactId}-${version}.jar(或war)
            配置后,打包产物名称会直接使用该标签的值,此处最终打包结果为MyJar.jar(或war)
         -->
        <finalName>MyJar</finalName>

        <!-- 
            resources节点:配置项目构建过程中需要被打包的资源文件集合
            作用:指定哪些目录下的资源文件需要被复制到最终的构建产物(如classes目录、jar包)中
            Maven默认只将src/main/resources目录下的文件视为资源文件进行打包
			此配置用于扩展额外资源目录
    	-->
        <resources>
            <resource>
                <!-- 
                    directory标签:指定资源文件所在的根目录(相对项目根路径)
                    此处配置为src/main/java,即扫描Java源码目录下的资源文件
            	-->
                <directory>src/main/java</directory>
                <includes>
                    <!-- 
                        include子节点:具体的文件匹配表达式(支持通配符)
                        1. ** :表示递归匹配任意多级子目录
                        2. *.xml :表示匹配所有后缀为.xml的文件
                        整体含义:匹配src/main/java目录下(包括所有子目录)的所有.xml文件
                    -->
                    <include>**/*.xml</include>
                </includes>
            </resource>
        </resources>
        
        <plugins>
            <!-- 配置Java编译插件 -->
            <plugin>
                <!-- Maven核心编译插件 -->
               	<groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                
                <!-- 配置编译参数:指定JDK源码版本和目标运行版本 -->
                <configuration>
                    <!-- 源码编译版本(如JDK 8) -->
                    <source>8</source>
                    <!-- 生成的字节码兼容版本(如JDK 8) -->
                    <target>8</target>
                    <!-- 可选:编码格式,避免中文注释编译乱码 -->
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

依赖范围

通过设置坐标的依赖范围(scope),可以设置对应jar包的作用范围:编译环境、测试环境、运行环境。项目中很多依赖只在开发阶段有用,打包部署到生产环境后完全不需要,如果不区分范围,这些依赖会被一起打包,造成产物体积臃肿。另外部分测试依赖包可能存在未修复的安全漏洞,或者包含敏感的调试逻辑,这些依赖留在生产环境中,会增加项目被攻击的风险,而通过scope限制其仅在测试环境生效,可规避这类问题。

依赖范围描述
compile (默认)编译依赖范围,默认值,不用写。对于编译环境、测试环境、运行环境都需要。
test测试依赖范围,仅测试阶段。即只能在src/test/java目录下使用该依赖。
provided已提供依赖范围,编译环境和测试环境生效。
runtime测试环境和运行环境生效。

Maven 依赖下载失败问题

失败原因:网络故障或者仓库服务器宕机,导致无法连接至Maven中央仓库
解决方案:检查网络连接和Maven仓库服务器状态

失败原因:依赖项的版本号或配置文件中的版本号错误,或者依赖项没有正确定义
解决方案:确保依赖项版本号与项目对应的版本号匹配,并检查POM文件中的依赖项是否正确

失败原因:本地Maven仓库或缓存被污染,导致Maven无法正确地使用现有的依赖项
解决方案:清除Maven仓库缓存(lastUpdated文件),因为只要存在lastUpdated缓存文件,刷新也不会重新下载。本地仓库中,根据依赖的gav属性依次向下查找文件夹,最终删除内部的lastUpdated缓存文件,刷新重新下载即可。也可使用Bat脚本一键删除。

@echo off

rem 这里写你的仓库路径
set REPOSITORY_PATH=D:\TenSoFlow\Code\Maven\LuoChuanRepository

rem 正在搜索...
for /f "delims=" %%i in ('dir /b /s "%REPOSITORY_PATH%\*lastUpdated*"') do (
    echo %%i
    del /s /q "%%i"
)

rem 搜索完毕
pause

将上面Bat脚本中的仓库路径D:\TenSoFlow\Code\Maven\LuoChuanRepository替换成自己的本地仓库路径即可。

Maven 工程继承和聚合

Maven 继承是指在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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <!-- 父模块:继承SpringBoot父工程(用于统一SpringBoot版本) -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.3</version>
        <relativePath/>
    </parent>

    <groupId>com.luochuan</groupId>
    <artifactId>luochuan</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    
    <name>luochuan</name>
    <description>luochuan框架</description>
    
    <!-- 聚合模块必须是pom -->
    <packaging>pom</packaging>

    <!-- 统一管理依赖版本 -->
    <properties>
        <!-- Java版本 -->
        <java.version>8</java.version>
        <!-- Lombok版本 -->
        <lombok.version>1.18.20</lombok.version>
        <!-- Mybatis-Plus版本 -->
        <mybatis-plus.version>3.4.1</mybatis-plus.version>
        <!-- MySQL版本 -->
        <mysql.version>8.0.30</mysql.version>
        <!-- commons-lang3版本 -->
        <commons-lang3.version>3.14.0</commons-lang3.version>
        <!-- 日志实现版本 -->
        <logback.version>1.2.12</logback.version>
    </properties>

    <!-- 依赖管理只声明版本不实际引入 -->
    <!-- 注意:这里是dependencyManagement而不是dependencies -->
    <dependencyManagement>
        <dependencies>
            <!-- application启动模块依赖声明 -->
            <dependency>
                <groupId>com.luochuan</groupId>
                <artifactId>luochuan-application</artifactId>
                <version>${project.version}</version>
            </dependency>

            <!-- generator代码生成模块依赖声明 -->
            <dependency>
                <groupId>com.luochuan</groupId>
                <artifactId>luochuan-common</artifactId>
                <version>${project.version}</version>
            </dependency>

            <!-- Lombok可以通过注解来自动生成Java Set Get方法简化Java开发 -->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>${lombok.version}</version>
            </dependency>

            <!-- MyBatisPlus的SpringBoot Starter提供了集成MyBatisPlus的功能 -->
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
                <version>${mybatis-plus.version}</version>
            </dependency>

            <!-- MySQL数据库的官方JDBC驱动程序用于连接MySQL数据库 -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql.version}</version>
            </dependency>

            <!-- 对Java原生AP 的补充与增强提供了字符串、日期、对象、反射、异常、数组等高频场景的健壮工具类 -->
            <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-lang3</artifactId>
                <version>${commons-lang3.version}</version>
            </dependency>

            <!-- 日志实现 -->
            <dependency>
                <groupId>ch.qos.logback</groupId>
                <artifactId>logback-classic</artifactId>
                <version>${logback.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <!-- 聚合子模块 -->
    <modules>
        <module>luochuan-application</module>
        <module>luochuan-common</module>
    </modules>

    <build>
        <plugins>
            <!-- 仅配置编译插件,统一Java版本 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

评论
  • 按正序
  • 按倒序
  • 按热度
Powered by Waline v2.15.8