maven基础/java包管理器

Maven

  • 在构建java项目的时候,总是会碰到下载依赖和对项目结构的疑问,以下内容就是我对现在最常用之一的java包管理器maven的学习笔记

一、情景和作用以及前置步骤

1.1情景和作用

解决依赖管理和项目构建

  • 核心文件:pom.xml,类似于package.json,makefile文件

  • 类似于npm、make的作用

  • 当下载依赖的时候默认是先从本地仓库查找,如果没有去就去私服仓库(可以用Nexus配置)或者中央仓库寻找。

  • 项目的构建需要将源文件编译成一个jar包或war包,maven提供了自动化的标准流程,通过该流程可以实现自动化打包

1.2前置步骤

1.2.1安装maven
  1. 前备知识

    • 需要JDK版本>=1.7
  2. 下载链接

  3. 配置setting.json

    • 配置maven依赖安装路径

      xml 复制代码
      <localRepository><路径></localRepository>
    • 配置镜像源

      xml 复制代码
          <mirror>
            <id>aliyunmaven</id> 
            <mirrorOf>*</mirrorOf>
            <name>阿里云公共仓库</name>
            <url>https://maven.aliyun.com/repository/public</url>
          </mirror>
          <mirror>
            <id>maven-default-http-blocker</id>   <!-- 镜像的唯一表示 -->
            <mirrorOf>external:http:*</mirrorOf>  <!-- 镜像的范围,*表示匹配所有,该镜像只对http协议有效,https协议无效,-->
            <name>Pseudo repository to mirror external repositories initially using HTTP.</name>
            <url>http://0.0.0.0/</url>
            <blocked>true</blocked>
          </mirror>
    • (可以不配)指定maven默认打包java项目的JDK版本。但是因为项目中的pom.xml优先级高于它,java项目一般也会在pom.xml中指定JDK版本

      xml 复制代码
          <profile> 
            <id>jdk-1.8</id>  
            <activation>
      		    <activeByDefault>true</activeByDefault>
              <jdk>1.8</jdk>  
            </activation>  
              
            <properties>  
              <maven.compiler.source>1.8</maven.compiler.source>  
              <maven.compiler.target>1.8</maven.compiler.target>  
              <maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>  
            </properties>   
          </profile>
1.2.2简单开始maven
  1. 创建maven项目

    shell 复制代码
    mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-app -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.5 -DinteractiveMode=false
    • -DgroupId代表的是域名(通常反过来写)
    • -DartifactId是项目的唯一标识
    • -DarchetypeArtifactId项目的目录结构
    shell 复制代码
    目录结构
    my-app
    |-- pom.xml
    `-- src
        |-- main
        |   `-- java
        |       `-- com
        |           `-- mycompany
        |               `-- app
        |                   `-- App.java
        `-- test
            `-- java
                `-- com
                    `-- mycompany
                        `-- app
                            `-- AppTest.java
  2. 流程

    • 编译项目

      shell 复制代码
      mvn compile
    • 测试项目(测试代码的逻辑性)

      shell 复制代码
      mvn test
    • 打包项目(打包使得源代码和环境集合在一起,实现可移植性,适合企业开发)

      shell 复制代码
       mvn package
    • 执行项目

      • 如果你的项目是一个 可执行的 JAR 文件 ,你可以使用 java -jar 命令来运行它。首先,确保你的 pom.xml 文件中有一个 mainClass 配置用于指定主类。典型的配置如下:

        xml 复制代码
        <build>
          <plugins>
            <plugin>
              <groupId>org.apache.maven.plugins</groupId>
              <artifactId>maven-jar-plugin</artifactId>
              <version>3.2.0</version>
              <configuration>
                <archive>
                  <manifest>
                    <mainClass>com.mycompany.app.App</mainClass> <!-- 主类路径 -->
                  </manifest>
                </archive>
              </configuration>
            </plugin>
          </plugins>
        </build>
        shell 复制代码
        java -jar target/my-app-1.0-SNAPSHOT.jar
      • 直接运行项目中的主类

        • 如果你想直接运行某个类(不打包),可以使用 Maven 的 exec:java 插件。首先,确保在 pom.xml 文件中添加了 exec-maven-plugin 插件:

          xml 复制代码
          <build>
            <plugins>
              <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>3.0.0</version>
                <configuration>
                  <mainClass>com.mycompany.app.App</mainClass> <!-- 主类路径 -->
                </configuration>
              </plugin>
            </plugins>
          </build>
          shell 复制代码
          mvn exec:java -Dexec.mainClass="com.mycompany.app.App"
    • 清理项目

      shell 复制代码
      mvn clean
1.2.3idea中使用maven
  1. 创建项目,大部分框架都集成了maven,都有默认的maven项目目录结构,默认配置。可以通过下图的地方去修改maven配置

    这里maven home path就是自己的maven下载路径,改User setting file<setting.xml的路径>和Local repository记得勾选旁边的Override。

二、基础知识

2.1Maven的生命周期和插件

  1. 右边maven中的Profiles(比如不同java版本)是setting.json中配置的,如果配置多个就会有多个,但是一般的Spring项目没有的,因为在生成项目的时候,我们会指定很多参数,并不是单纯的maven项目,是在pom.xml中配置的,当然也可以实现在pom.xml中配置实现不同版本的切换

  2. Lifecycle这些生命周期是依靠于下方的一个或多个插件的,idea中可以直接点击生命周期执行

    阶段 描述 对应命令
    clean 清理项目,删除上一次构建生成的文件 mvn clean
    validate 验证项目是否正确且所有必要信息都可用 mvn validate
    compile 编译源代码 mvn compile
    test 使用适当的测试框架执行测试 mvn test
    package 将编译后的代码打包成可分发格式,如 JAR 或 WAR mvn package
    verify 运行任何检查,验证包的有效性 mvn verify
    install 将包安装到本地 Maven 仓库 mvn install
    site 生成项目的站点文档 mvn site
  • 一般的顺序也是这样
  • groupId、artifactId、version构成了jar包的唯一标识
  • 命令行支持mvn <阶段> <阶段>这种操作,是先执行第一个任务,再第二个任务

2.2maven的核心特性:依赖下载管理

  1. scope标签

    • 属性

      下面是用 Markdown 格式编写的 Maven scope 属性作用总结表:

      Scope 编译时 测试时 运行时 最终打包 用途
      compile 默认值,依赖在编译、测试、运行时都可用,通常用于核心库。
      runtime 依赖在运行时可用,编译时不可用,适用于编译时不需要但运行时需要的库(如 JDBC 驱动)。
      test 仅在测试阶段可用,不会包含在最终构建中,适用于测试框架(如 JUnit、Mockito)。
      system 使用本地文件路径的依赖,不从 Maven 仓库下载,需通过 systemPath 指定。
      provided 编译、测试时可用,运行时由目标环境提供,不打包在最终项目中(如 Servlet API)。
    • 极其不推荐system,因为转移开发环境很容易出问题

    • pom.xml中下载依赖的时候,本身就会通过配置过的maven的repository仓库来寻找依赖,找到了就不用下载。也可以通过把scpoed属性值改为system,再加上system-path路径使得使用别的路径的依赖,但上方也说了极其不推荐

  2. 添加依赖

    • 进入maven的repository仓库网站

      https://mvnrepository.com/

    • 搜索需要下载的依赖

    • 选择版本号

    • 点击版本号,复制链接,并加入pom.xml

  3. 依赖传递

    • 直接写在pom.xml的依赖是直接依赖,写到xml中的文件有可能依赖别的文件,依赖的文件就和现在的项目的关系就是间接依赖了,maven会帮我们自动解析,但是要注意,maven只会解析属性scpoed值为compile的依赖(但如果是在父模块中定义的就不是了)
  4. 依赖冲突:使用同一个依赖的不同版本

    • 最短路径选择:当你拉取其他人的仓库时,如果该仓库依赖于不同版本的同一库,Maven 会根据依赖树的最短路径原则选择版本。这意味着如果某个依赖通过更少的中间依赖达到目的,它会被优先选择。

    • 优先级 :在自己的项目中,列出的依赖顺序也会影响最终选择的版本。通常,首先出现的依赖会被优先使用,这使得在 pom.xml 中的依赖顺序变得重要。

    • 手动解决依赖

      • 当一个模块使用了其它两个模块的jar包,每个jar包都有spring-jdbc,但版本不一样,这个时候,maven有自动的调节方案,可以看到child-test3这个模块的jdbc黑了



        • 如果我就要使用test3的怎么办呢

          1. 使用exclusions标签,再在里面加入单数的exclusion标签,添加要忽略的jar包的坐标,注意不需要版本号,因为会把该jar包所有的这个类型的依赖全部忽略掉,然后重启,发现test2没了,test3也黑,是因为ideabug,重启后就ok了

          2. 在所需的jar包的pom.xml文件中加入optional选项,true就是屏蔽,有图和第一个方法有同样bug,重启idea即可

  5. 父子项目

    • 当多个子模块需要的依赖都一样,可以通过父模块安装好,供子模块使用,父模块不会打包。比如电商平台会有:商品模块、用户模块等

    • 新建一个项目,父模块不需要打包等操作,可以直接删除src文件夹。

      • 注意把父模块中的pom.xml中的packaging改为pom,表示不需要打包,一般来说都是jar包,web项目为war包。
      • 然后会出现modules标签,里面是子模块的信息。
    • 新建一个子模块

      子模块的pom.xml,parent直接移用了父模块的坐标,子模块的groupId直接继承父模块的groupId

    • 注意spring,项目不会直接继承夫模块的groupId,而是单独拥有,会有以下好处

      1. 模块化和独立性

      • 使用不同的 groupId 可以使每个子模块更加独立,便于管理和维护。这样,子模块可以在不同的项目中独立使用,避免了依赖于父模块的紧耦合关系。

      2. 版本控制

      • 不同的 groupId 可以让子模块拥有独立的版本控制。这意味着可以单独更新子模块的版本,而不影响父模块或其他子模块。

      3. 发布和分发

      • 当子模块需要单独发布到 Maven 仓库时,使用不同的 groupId 可以确保它们可以被其他项目直接引用。这在企业级开发中尤其常见。

      4. 清晰的组织结构

      • 采用不同的 groupId 可以帮助在项目中建立更清晰的层次结构和模块组织,便于团队成员理解各个模块的用途和职责。

      5. 避免冲突

      • 如果子模块和父模块的 groupId 相同,可能会在依赖解析时引发混淆或冲突。使用不同的 groupId 可以避免这种情况。

      6. 符合 Maven 约定

      • Maven 鼓励通过 groupId 来反映项目的组织结构或领域。不同的 groupId 可以更好地反映子模块的业务逻辑或功能特性。
  • dependencyManagement

    • 在这个标签中定义的模块不会被子模块直接继承,在子模块中再引入模块,不写版本号,就是直接引用父模块中的


  • spring.version多个依赖使用同个版本

    使用方式如图

  • 参考GeekHour'

  • 如有问题,可以反馈给我,感谢读者的观看啦

相关推荐
iQM7515 分钟前
Spring Boot 中实现任务后台处理的几种常见方式
java·spring boot·后端
2401_8576176217 分钟前
创新学生宿舍管理:Spring Boot框架实践
java·spring boot·后端
六点半88818 分钟前
【C++】 vector 迭代器失效问题
开发语言·c++·青少年编程
shall_zhao20 分钟前
Spring异常处理-@ExceptionHandler-@ControllerAdvice-全局异常处理
java·spring
海海不掉头发23 分钟前
【已解决】如何使用JAVA 语言实现二分查找-二分搜索折半查找【算法】手把手学会二分查找【数据结构与算法】
java·开发语言·算法
Data 3171 小时前
关于 SQL 的 JOIN 操作
java·大数据·数据库·数据仓库·sql
BeyondESH2 小时前
C++—单例设计模式
java·c++·设计模式
好奇的菜鸟2 小时前
探索 JUnit 5:下一代 Java 测试框架
java·开发语言·junit
爱吃土豆的程序员2 小时前
Lucene 倒排索引原理详解:深入探讨相关算法设计
java·算法·elasticsearch·全文检索·lucene
林小果12 小时前
桥接模式
java·开发语言·设计模式