• Springboot 打包神器Maven 保姆级教程


    在这里插入图片描述

    一、介绍

    Maven 是基于项目对象模型 (POM project object model),可以通过一小段描述信息(配置)来管理项目的构建,报告和文档的软件项目管理工具,简单的说就是用来管理项目所需要的依赖且管理项目构建的工具。

    二、maven 作用

    Maven 官网:https://maven.apache.org
    Maven 仓库:https://search.maven.org/search
    
    • 1
    • 2
    1. 在开发中,为了保证编译通过,我们会到处去寻找 jar 包,当编译通过了,运行的时候,却发现 “ClassNotFoundException”,我们想到的是,难道还差 jar 包?
    2. 每个 Java 项目的目录结构都没有一个统一的标准,配置文件到处都是,单元测试代码到底应该放在那里也没有一个权威的规范。
    3. 因此,我们就要用到 Maven(使用 Ant 也可以,不过编写 Ant 的 xml 脚本比较麻烦)---- 一个项目管理工具。
    4. Maven 主要做了两件事:
      • 统一开发规范与工具
      • 统一管理 jar 包

    三、maven 的生命周期

    maven 把项目的构建划分为不同的生命周期(lifecycle)。包括:

    1. 验证(validate):验证项目是否正确
    2. 编译(compile):编译项目的源代码
    3. 测试(test):使用合适的单元测试框架测试编译的源代码。这些测试不应该要求代码被打包或部署
    4. 打包(package):项目打包成 war 包或 jar 包
    5. 验证(verify)
    6. 安装(install):打包后的 jar 包,安装要本地的 repository 中。
    7. 部署(deploy)

    maven 中所有的执行动作(goal)都需要指明自己在这个过程中的执行位置,然后 maven 执行的时候,就依照过程的发展一次调用这些 goal 进行各种处理。
    这个也是 maven 的一个基本调度机制。一般来说,位置稍后的过程都会依赖于之前的过程。当然,maven 同样提供了配置文件,可以依照用户要求,跳过某些阶段。

    三、maven 规范

    maven 使用如下几个要素来唯一定位某一个输出物:
    groupId;artifactId;packaging;version。

    1. groupId 公司、团体等。比如 Apache Software 的项目有以下 org。apache 开头的 groupId。
    2. artifactId 项目是唯一标识符。比如一个 helloworld 项目就叫 helloworld。
    3. packaging 项目打包输出的类型,默认是 jar 包,也可以为 war 包,产生一个 web 应用。
    4. version 一个项目的特定的版本。发布的项目有一个固定的版本表示来指向该项目的某一个特定的版本。而正在开发中的项目可以用一个特殊的标识,这种标识个版本加上一个 “SNAPSHOT” 的标记。

    maven在版本管理时候可以使用几个特殊的字符串 SNAPSHOT ,LATEST ,RELEASE 。比如"1.0-SNAPSHOT"。各个部分的含义和处理逻辑如下说明:
    1. SNAPSHOT 如果一个版本包含字符串"SNAPSHOT",Maven就会在安装或发布这个组件的时候将该符号展开为一个日期和时间值,转换为UTC时间。例如,"1.0-SNAPSHOT"会在2010年5月5日下午2点10分发布时候变成1.0-20100505-141000-1。这个词只能用于开发过程中,因为一般来说,项目组都会频繁发布一些版本,最后实际发布的时候,会在这些snapshot版本中寻找一个稳定的,用于正式发布,比如1.4版本发布之前,就会有一系列的1.4-SNAPSHOT,而实际发布的1.4,也是从中拿出来的一个稳定版。
    2. LATEST 指某个特定构件的最新发布,这个发布可能是一个发布版,也可能是一个snapshot版,具体看哪个时间最后。
    3. RELEASE 指最后一个发布版

    四、maven 项目依赖

    1. 多模块依赖和继承

    项目结构图:

    parent
        ├─childA(model层)
        │  └─pom.xml(jar)
        ├─childB(web层)
        │  └─pom.xml(war)
        └─pom.xml(pom)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    1. parent 中执行 mvn install 就能将 childA 和 childB 一起编译
      parent 的 pom.xml 做如下配置:
    com.ht
    parent
    1.0-SNAPSHOT
    pom    
    
    
        childA   
        childB
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    childA 和 childB 的 pom.xml 都需要配置 parent,防止引入的包冲突 (如果不加 parent,会分别去编译他们引入的依赖,会重复引入包):

    
    
        parent
        com.ht
        1.0-SNAPSHOT
    
    4.0.0
    childA
    jar
    
    
    
        parent
        com.ht
        1.0-SNAPSHOT
    
    4.0.0
    childB
    war
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    1. 子 pom 间存在引用关系,比如 childB 引用到了 childA 的 jar 包
    
       com.module
       childA       
       1.0-SNAPSHOT
    
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2. 子项目继承父项目的依赖

    parent 中加上 dependencyManagement,child 项目就可以继承 parent 项目的依赖,并且在 child 中可以不用加 version 了。

    
            
                
                    org.springframework.cloud
                    spring-cloud-dependencies
                    ${spring-cloud.version}
                    pom
                    import
                
            
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    子项目直接引入 parent的依赖 就行

    3. 依赖范围

    dependency 依赖关系中 Scope(范围)的作用:主要管理依赖的部署。
    如果不显示执行 删除线格式 属性时,默认 compile
    scope 属性包括(5 个值):

      1. compile(编译范围):编译范围的在所有的classpath中可用,同时它们也会被打包
      1. provided(已提供范围):表示部署的环境当中有某容器已经提供了该jar包,只在编译classpath(不是运行时)可用。它们不是传递性的,也不会被打包。例如,如果你开发了一个web应用,你可能在编译classpath中需要可用的Servlet API来编译一个servlet,但是你不会想要在打包好的WAR中包含这个Servlet API;这个Servlet API JAR由你的servlet容器(Tomcat)提供。
      1. runtime(运行时范围):只在运行和测试系统的时候需要,但在编译的时候不需要。
      1. test(测试范围):在一般的 编译和运行时都不需要,它们只有在测试编译和测试运行阶段可用。
      1. system (系统范围):该范围不推荐使用(你应该一直尽量去从公共或定制的Maven仓库中引用依赖)

    详细可参考:https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Dependency_Scope

    4. 可选依赖(Optional Dependencies)和依赖排除(Dependency Exclusions)

    maven 的依赖关系是有传递性的。如:A–>B,B–>C。但有时候,项目 A 可能不是必需依赖 C,因此需要在项目 A 中排除对 A 的依赖。在 maven 的依赖管理中,有两种方式可以对依赖关系进行,分别是可选依赖(Optional Dependencies)以及依赖排除(Dependency Exclusions)。

    4.1 可选依赖 optional

    当一个项目 A 依赖另一个项目 B 时,项目 A 可能很少一部分功能用到了项目 B,此时就可以在 A 中配置对 B 的可选依赖。举例来说,一个类似 hibernate 的项目,它支持对 mysql、oracle 等各种数据库的支持,但是在引用这个项目时,我们可能只用到其对 mysql 的支持,此时就可以在这个项目中配置可选依赖。
    配置可选依赖的原因:1、节约磁盘、内存等空间;2、避免license许可问题;3、避免类路径问题,等等

    
      sample.ProjectB
      Project-B
      1.0
      compile
      true
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    假设以上配置是项目 A 的配置,即:Project-A --> Project-B。在编译项目 A 时,是可以正常通过的。
    如果有一个新的项目 X 依赖 A,即:Project-X -> Project-A。此时项目 X 就不会依赖项目 B 了。如果项目 X 用到了涉及项目 B 的功能,那么就需要在 pom.xml 中重新配置对项目 B 的依赖。

    4.2 依赖排除 (exclusions)

    当一个项目 A 依赖项目 B,而项目 B 同时依赖项目 C,如果项目 A 中因为各种原因不想引用项目 C,在配置项目 B 的依赖时,可以排除对 C 的依赖。
    示例(假设配置的是 A 的 pom.xml,依赖关系为:A --> B; B --> C):

    
      sample.ProjectB
      Project-B
      1.0
      compile
      
        
          sample.ProjectC
          Project-C
        
       
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    当然,对于多重依赖,配置也很简单,参考如下示例:
    项目 A–> 项目 B --> 项目 C --> 项目 D --> 项目 E

    
      sample.ProjectB
      Project-B
      1.0-SNAPSHOT
      
        
          sample.ProjectE
          Project-E
        
      
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    5. dependency 中的 type 属性

    dependency 中 type 默认为 jar 即引入一个特定的 jar 包。那么为什么还会有 type 为 pom 呢?
    当我们需要引入很多 jar 包的时候会导致 pom.xml 过大,我们可以想到的一种解决方案是定义一个父项目,但是父项目只有一个,也有可能导致父项目的 pom.xml 文件过大。这个时候我们引进来一个 type 为 pom,意味着我们可以将所有的 jar 包打包成一个 pom,然后我们依赖了 pom,即可以下载下来所有依赖的 jar 包

    
                    org.springframework.boot
                    spring-boot-dependencies
                    ${spring.boot.version}
                    pom
                    import
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    6.properties 标签

    用户可以使用该类属性引用 POM 文件中对应元素的值。如 ${project.artifactId} 就对应了 元素的值,常用的 POM 属性包括:
    ${project.build.sourceDirectory}: 项目的主源码目录,默认为 src/main/java/
    ${project.build.testSourceDirectory}: 项目的测试源码目录,默认为 src/test/java/
    ${project.build.directory} : 项目构建输出目录,默认为 target/
    ${project.outputDirectory} : 项目主代码编译输出目录,默认为 target/classes/
    ${project.testOutputDirectory}:项目测试主代码输出目录,默认为 target/testclasses/
    ${project.groupId}:项目的 groupId
    ${project.artifactId}:项目的 artifactId
    ${project.version} : 项 目 的 v e r s i o n , 与 {project.version}:项目的 version, 与 project.version:项目的 version, 与 {version} 等价
    p r o j e c t . b u i l d . f i n a l N a m e :项目打包输出文件的名称,默认为 {project.build.finalName} : 项目打包输出文件的名称,默认为 project.build.finalName:项目打包输出文件的名称,默认为{project.artifactId}-${project.version}

    例子:

    
     UTF-8
     2.1.6_RELEASE
     1.8
      1.8
     
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    五、Maven 插件机制

    1. Maven 默认插件

    不配置 Plugin 时,Maven 默认会使用以下插件。如果针对各个 plugin 有特殊配置的话,需要显示指定 plugin 和 属性配置。
    其中的 build 标签描述了如何来编译及打包项目,而具体的编译和打包工作是通过 build 中配置的 plugin 来完成。当然 plugin 配置不是必须的,默认情况下,Maven 会绑定以下几个插件来完成基本操作。

    pluginfunctionlife cycle phase
    maven-clean-plugin清理上一次执行创建的 target 文件clean
    maven-resources-plugin处理资源文件resources,testResources
    maven-compiler-plugin编译 Java 代码compile、testCompile
    maven-surefire-plugin执行单元测试文件test
    maven-jar-plugin创建 jarpackage
    maven-install-plugin清理上一次执行创建的 target 文件拷贝 jar 到本地的 maven 仓库 /repository 下面清理上一次执行创建的 target 文件install
    maven-deploy-plugin发布 jadeploy
    maven-site-plugin生成文档site

    maven-site-plugin:将工程所有文档生成网站,生成的网站界面默认和apache的项目站点类似,但是其文档用doxia格式写的,目前不支持docbook,需要用其他插件配合才能支持。需要指出的是,在maven 2.x系列中和maven3.x的site命令处理是不同的,在旧版本中,用 mvn site 命令可以生成reporting节点中的所有报表,但是在maven3中,reporting过时了,要把这些内容作为 maven-site-plugin的configuration的内容才行。

    
        
        
            
                src/main/java
                true 
                
                    **/*.xml
                
            
            
                src/main/resources
                true
                
                    **/*.properties
                    *.xml
                    *.dic
                    *.txt
                
            
            
                src/main/resources
                false
                
                    *.p12
                
            
        
    
    
    
        
            
            
                maven-compiler-plugin
                3.1
                
                    1.8
                    1.8
                    UTF-8
                
            
            
            
            
                org.apache.maven.plugins
                maven-resources-plugin
                2.6
                
                    UTF-8
                
            
        
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60

    2.maven 常用的插件

    spring-boot-maven-plugin
    当使用 SpringBoot 开发项目的时候,会使用到 spring-boot-maven-plugin 插件
    Spring Boot Maven plugin 有 5 个 Goals:

    命令说明
    spring-boot:repackage默认 goal。在 mvn package 之后,再次打包可执行的 jar/war, 并将 mvn package 生成的软件包重命名为 *.original
    spring-boot:run运行 Spring Boot 应用
    spring-boot:start在 mvn integration-test 阶段,进行 Spring Boot 应用生命周期的管理
    spring-boot:stop在 mvn integration-test 阶段,进行 Spring Boot 应用生命周期的管理
    spring-boot:build-info生成 Actuator 使用的构建信息文件 build-info.properties

    其中比较重要的命令是:

    mvn package spring-boot:repackage
    
    • 1

    执行后会看到生成的两个 jar 文件,一个是 *.jar,另一个是 *.jar.original。
    这是由于在执行上述命令的过程中,Maven 首先在 package 阶段打包生成 *.jar 文件;然后执行 spring-boot:repackage 重新打包

    2.1 maven-source-plugin

    maven-source-plugin 提供项目自动将源码打包并发布的功能,在需要发布源码项目的 pom.xml 文件中添加如下代码即可:

    
        org.apache.maven.plugins
        maven-source-plugin
        
        
        
            
                attach-sources
                
                    jar
                
            
        
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    执行 mvn install,maven 会自动将 source install 到 repository 。
    执行 mvn deploy,maven 会自动将 source deploy 到 remote-repository 。
    执行 mvn source:jar,单独打包源码。
    注意:在多项目构建中,将 source-plugin 置于顶层或 parent 的 pom 中并不会发挥作用,必须置于具体项目的 pom 中。

    六、mvn 命令行参数

    参数可选列表

    mvn -v, –version 显示版本信息;

    mvn -V, –show-version 显示版本信息后继续执行Maven其他目标;

    mvn -h, –help 显示帮助信息; mvn -e, –errors 控制Maven的日志级别,产生执行错误相关消息;

    mvn -X, –debug 控制Maven的日志级别,产生执行调试信息;

    mvn -q, –quiet 控制Maven的日志级别,仅仅显示错误;

    mvn -Pxxx 激活 id 为 xxx的profile (如有多个,用逗号隔开);
    mvn -Dxxx=yyy 指定Java全局属性;

    mvn -o , –offline 运行offline模式,不联网更新依赖;

    mvn -N, –non-recursive 仅在当前项目模块执行命令,不构建子模块;

    mvn -pl, –module_name 在指定模块上执行命令;

    mvn -ff, –fail-fast 遇到构建失败就直接退出;

    mvn -fn, –fail-never 无论项目结果如何,构建从不失败;

    mvn -fae, –fail-at-end 仅影响构建结果,允许不受影响的构建继续;

    mvn -C, –strict-checksums 如果校验码不匹配的话,构建失败;

    mvn -c, –lax-checksums 如果校验码不匹配的话,产生告警;

    mvn -U 强制更新snapshot类型的插件或依赖库(否则maven一天只会更新一次snapshot依赖);

    mvn -npu, –no-plugin-updates 对任何相关的注册插件,不进行最新检查(使用该选项使Maven表现出稳定行为,该稳定行为基于本地仓库当前可用的所有插件版本);

    mvn -cpu, –check-plugin-updates 对任何相关的注册插件,强制进行最新检查(即使项目POM里明确规定了Maven插件版本,还是会强制更新);

    mvn -up, –update-plugins [mvn -cpu]的同义词;

    mvn -B, –batch-mode 在非交互(批处理)模式下运行(该模式下,当Mven需要输入时,它不会停下来接受用户的输入,而是使用合理的默认值);

    mvn -f, –file 强制使用备用的POM文件; mvn -s, –settings 用户配置文件的备用路径;
    mvn -gs, –global-settings 全局配置文件的备用路径;

    mvn -emp, –encrypt-master-password 加密主安全密码,存储到Maven settings文件里;

    mvn -ep, –encrypt-password 加密服务器密码,存储到Maven settings文件里;

    mvn -npr, –no-plugin-registry 对插件版本不使用~/.m2/plugin-registry.xml(插件注册表)里的配置

    -D代表(Properties属性)

    用法:

    mvn -DpropertyName=propertyValue clean package
    
    • 1

    如果pom.xml中不存在名为propertyName属性,它将被设置

    如果pom.xml中已存在propertyName属性,其(propertyValue)值将会传递给参数

    要发送多个变量,请使用多个空格分隔符加-D:

    mvn -DpropA=valueA -DpropB=valueB -DpropC=valueC clean package

    举例:

    pom.xml
    
        myDefaultTheme
    
    
    • 1
    • 2
    • 3
    • 4

    执行以下命令:

    mvn -Dtheme=halloween clean package
    
    • 1

    打包后的pom.xml文件内容已被指定的参数替换:

    <properties>
        <theme>halloweentheme>
    properties>
    
    • 1
    • 2
    • 3

    -P代表(Profiles配置文件,指定环境)

    指定的中,可以通过-P进行传递或者赋值
    
    • 1

    举例

    pom.xml如下:

    <profiles>
          <profile>
              <id>testid>
              ...
          profile>
    profiles>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    则触发profile中的配置的命令为:mvn test -Ptest

    在譬如pom.xml如下:

    <profile>
       <id>testid>
       <activation>
          <property>
             <name>envname>
             <value>testvalue>
          property>
       activation>
       ...
    profile>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    则触发profile中的配置的命令为:mvn test -Penv=test

  • 相关阅读:
    HTTPS加密过程
    拥抱下一代前端工具链-Vue老项目迁移Vite探索
    深圳大学计软《程序设计基础》MOOC实验一:数据类型、运算符、输入输出
    开源相机管理库Aravis例程学习(二)——连续采集multiple-acquisition-main-thread
    C#调用WebService的方法介绍
    Apache Pulsar 系列 —— 深入理解 Bookie GC 回收机制
    什么是线上优雅停机和调整线程池参数?
    Python实验二
    Visual Studio的调试bug
    Spring-06 Xml和注解方式配置Aop
  • 原文地址:https://blog.csdn.net/agonie201218/article/details/126178757