Maven 那点不为人知的事


title: Maven 那点不为人知的事
date: 2020/11/24 03:48


1、Maven 构建的生命周期

Maven 将一个整体任务划分为一个个的阶段,按顺序依次执行,也可以指定该任务执行到中间的某个阶段结束。执行命令为 mvm 阶段名(例如:mvn pre-clean)

image

clean 生命周期

包含以下阶段(pashe):

  • pre-clean:执行一些清理前需要完成的工作。
  • clean:清理上一次构建生成的文件。
  • post-clean:执行一些清理后需要完成的工作。

default 生命周期

包含以下阶段,default 生命周期定义了真正构建时所需要执行的所有步骤,它是所有生命周期中最核心的部分

生命周期阶段 描述
validate 检查工程配置是否正确,完成构建过程的所有必要信息是否能够获取到。
initialize 初始化构建状态,例如设置属性。
generate-sources 生成编译阶段需要包含的任何源码文件。
process-sources 处理源代码,例如,过滤任何值(filter any value)。
generate-resources 生成工程包中需要包含的资源文件。
process-resources 拷贝和处理资源文件到目的目录中,为打包阶段做准备。
compile 编译工程源码。
process-classes 处理编译生成的文件,例如 Java Class 字节码的加强和优化。
generate-test-sources 生成编译阶段需要包含的任何测试源代码。
process-test-sources 处理测试源代码,例如,过滤任何值(filter any values)。
test-compile 编译测试源代码到测试目的目录。
process-test-classes 处理测试代码文件编译后生成的文件。
test 使用适当的单元测试框架(例如JUnit)运行测试。
prepare-package 在真正打包之前,为准备打包执行任何必要的操作。
package 获取编译后的代码,并按照可发布的格式进行打包,例如 JAR、WAR 或者 EAR 文件。
pre-integration-test 在集成测试执行之前,执行所需的操作。例如,设置所需的环境变量。
integration-test 处理和部署必须的工程包到集成测试能够运行的环境中。
post-integration-test 在集成测试被执行后执行必要的操作。例如,清理环境。
verify 运行检查操作来验证工程包是有效的,并满足质量要求。
install 安装工程包到本地仓库中,该仓库可以作为本地其他工程的依赖。
deploy 拷贝最终的工程包到远程仓库中,以共享给其他开发人员和工程。

site 生命周期

Maven Site 插件一般用来创建新的报告文档、部署站点等。包含以下阶段:

  • pre-site:执行一些在生成项目站点之前需要完成的工作。
  • site:生成项目站点文档。
  • post-site:执行一些在生成项目站点之后需要完成的工作。
  • site-deploy:将生成的项目站点发布到服务器上。

2、阶段与插件的关系

阶段相当于观察者模式中的消息发布者,而各个插件是消息订阅者,当用户执行某个命令,触发到了某个阶段的时候,他就会通知插件,插件就会执行它配置好的目标(goal)。

示例:SpringBoot 插件


    
        org.springframework.boot
        spring-boot-maven-plugin
    

他属于 default 生命周期,绑定到的阶段为 package 阶段,该插件的默认目标为 repackage。

image

SpringBoot 插件的配置


    org.springframework.boot
    spring-boot-maven-plugin
    
    
        repackage
        package  
        
            repackage  
        
    
    
    
        ${start-class}
    

image

3、依赖管理 标签

compile

默认 scope,编译、测试、运行都需要这个依赖。

provided

编译、测试时需要,运行和打包不需要。

scope 为 provided 的依赖一般是由 JDK 或者容器(例如 Tomcat)所提供的 jar 包,为了编译通过而添加的,

runtime

编译时不需要,运行、测试、打包时需要。

一般用于运行时通过反射调用的类,例如数据库驱动。

test

编译、运行、打包时不需要,测试时需要。

system & systemPath

直接通过系统路径进行引用的 jar 包,编译、测试、运行都需要这个依赖。



    org.mozilla.intl
    chardet
    1.0
    system
    ${project.basedir}/src/main/resources/lib/chardet-1.0.jar

import

将其他 pom 文件中的 dependencyManagement 引入到当前 pom 文件中的 dependencyManagement。

一般父 pom 文件主要就是做依赖管理的,但是 maven 只支持单继承,但是我们假如想要引入多个依赖管理就需要 import 这个 scope 了。

image

其他 —— 依赖是否传递 optional

当项目自身被依赖时,标注依赖是否传递。用于连续依赖时使用。

假设我有一个 base 项目,web 项目需要引用他,base 项目中引入了 spring-context.jar,但是使用了 optional 域,那么当 web 项目引用 base 打成的 jar 包的时候,并不会引入 spring-context 这个 jar 包。


    org.springframework
    spring-context
    true     

4、依赖冲突

一个项目A,通过不同依赖传递路径依赖于X,若在不同路径下传递过来的X版本不同,那么A应该导入哪个版本的X包呢?

当出现依赖冲突的时候,maven 会根据以下 3 种原则来进行解决:

1)路径近者优先原则

如果依赖路径的长度不同,则“短路优先”:

  • A —>B —>C —>D —> E —> X(version 0.0.1)
  • A —>F —>X(version 0.0.2)

则 A 依赖于 X(version 0.0.2)。


 
    
    
        org.springframework
        spring-context
        4.2.4.RELEASE
    
 
    
    
        org.apache.struts
        struts2-spring-plugin
        2.3.24
    
 
    
 
    
        org.springframework
        spring-beans
        4.2.5.RELEASE
    
     

2)先声明优先原则

  • A —> E —> X(version 0.0.1)
  • A —> F —> X(version 0.0.2)

则在项目 A 的中,E、F 哪个先引入则 A 依赖哪条路径的 X。


 
    
    
 
    
    
        org.springframework
        spring-context
        4.2.4.RELEASE
    
 
    
    
        org.apache.struts
        struts2-spring-plugin
        2.3.24
    
 

3)排除原则


    org.apache.struts
    struts2-spring-plugin
    2.3.24

    
        
            org.springframework
            spring-beans
        
    

5、setting.xml 文件解析

1)localRepository

image

2)proxy

image

3)servers

image

4)mirror

image
image

5)profile

image

6)activeProfiles

image
image

强烈建议看下这篇文章,这篇文章对 setting.xml 中的每一个配置项都进行了详细的说明。

快照版(SNAPSHOT) & 发布版(RELEASE)

maven 中的仓库分为两种,snapshot 快照仓库和 release 发布仓库。

快照仓库用于保存开发过程中的不稳定版本发布仓库则是用来保存稳定的发行版本

定义一个组件/模块为快照版本,只需要在 pom 文件中在该模块的版本号后加上 -SNAPSHOT 即可(注意这里必须是大写)。

release 版本不允许修改,每次对 release 版本修改和发布必须提升版本号。而 snapshot 一般是开发过程中的迭代版本snapshot 更新时不需要提升版本号,从而引用的项目可以不修改版本号自动下载构建

image

6、pom.xml 解析


    
    4.0.0
    
    com.ouyang.maven
    
    maven-test
    
    0.0.1-SNAPSHOT
    
    jar
    
    maven-test
    
    http://maven.apache.org
    
    
    
    
    
    
    
    

    
    
        
        
            distcentral
            libs-release
            http://elb-791125809.cn-northwest-1.elb.amazonaws.com.cn:5336/artifactory/libs-release
        
        
        
            distsnapshots
            libs-snapshot
            http://elb-791125809.cn-northwest-1.elb.amazonaws.com.cn:5336/artifactory/libs-snapshot
        
    
 
    
    
        UTF-8
    
 
    
        
            junit
            junit
            3.8.1
            
            test
            
            
            
            
                
            
        
    
    
    
        
    
 
    
        
        
            
                org.apache.maven.plugins
                maven-source-plugin
                3.0.1
                
                    
                        package
                        
                            jar-no-fork
                        
                    
                
            
        
        
            
                
                src/main/resources
                
                
                    *.properties
                    *.yaml
                
            
            
                src/main/resources
                true
                
                
                    bootstrap.properties
                    bootstrap.yaml
                    application.properties
                    application-${profile.active}.properties
                    application.yaml
                    application-${profile.active}.yaml
                
            
        
    


    
    
    
    
 

super pom

所有的 POM 都继承自一个父 POM(无论是否显式定义了这个父 POM)。父 POM 也被称作 Super POM,它包含了一些可以被继承的默认设置。

Maven 使用 effective pom(指Super pom 加上工程自己的配置)来执行相关的目标,它帮助开发者在 pom.xml 中做尽可能少的配置,当然这些配置可以被方便的重写。

查看 Super POM 默认配置的一个简单方法是执行以下命令:mvn help:effective-pom

image
image
image

正是通过这个 super pom 才简化了我们的构建过程,这正是“约定优于配置”,开发者不需要再关心每一个配置细节。Maven 为工程提供了合理的默认行为。当创建 Maven 工程时,Maven 会创建默认的工程结构。开发者只需要合理的放置文件,而在 pom.xml 中不再需要定义任何配置

7、mvn install 到仓库的文件结构

metadate.xml

发布版(RELEASE)jar 包的目录结构很简单,里面只有一个 jar 包和这个 jar 包所引用的 pom.xml,如果 maven 发现本地仓库有就不会再从远程仓库中获取。

但是快照版(SNAPSHOT)jar 包设计初衷就是为了在不改变版本号的前提下做快速迭代,所以它支持按照时间比对的方式来更新 jar,遵循如下逻辑:

  1. 检查 配置中的 updatePolicy (更新策略)的值,他支持的值有:always(总是更新)、daily (default,每天更新)、interval:X (X 为多少 min) 和 never(从不)
  2. 当 updatePolicy 策略判断通过,尝试获取 remote metadata.xml
  3. 之后比较 local & remote metadata.xml 中时间戳,决定是否执行 download
image
image

为啥 clean 的时候要下载这个

image

可能是每次使用 mvn xxx 命令的时候都会保持本地仓库的 jar 包时最新的?

xxx.lastUpdate

这些文件表示 maven 曾经尝试从服务器上下载依赖但是并未成功,为了节省带宽,他在文件中写入的特定时间段内不会进行再次尝试,使用 -U (例如:mvn -U clean)可以强制使其进行下载,当然直接删除这个文件也是可以的。

_remote.repositories 文件

使用Maven管理项目时,如果连不到远程仓库,但是明明本地仓库有对应的jar包,此时还是报找不到对应的包的原因,是maven3.x版本在从远程仓库下载资源后,会生成对应的_remote.repositories文件,标示该资源的来源,如果你有这个文件_remote.repositories,那就不会访问本地了,必须远程上有才行,否则就会报错。

解决方法是将_remote.repositories文件删除,亲测有效

https://zhuanlan.zhihu.com/p/65916665

8、将 jar 包发布到 maven 仓库(私服)

mvn deploy:deploy-file -DgroupId=com.dist -DartifactId=gis-base-supermap -Dversion=1.0.3-SNAPSHOT -Dpackaging=jar -Dfile=D:/SRC_产品_Supermap/gis-server-root/gis-base-supermap/target/gis-base-supermap-1.0.3-SNAPSHOT.jar -Durl=http://elb-791125809.cn-northwest-1.elb.amazonaws.com.cn:5336/artifactory/libs-snapshot/ -DrepositoryId=distsnapshots -DpomFile=D:\SRC_产品_Supermap\gis-server-root\gis-base-supermap\pom.xml

没测试过这个命令,但我猜测应该和直接双击 deploy 一样:

image

这种方式不会将打包的 jar 包的依赖一起打到私服中,所以要使用下面的这个命令:

mvn clean package deploy -pl map3d-api,xxx -am

-pl 表示模块列表,“dgp-server-ars-api ”这里可以写多个模块其一操作,逗号隔开

-am 是会级联到所有依赖

9、maven 搜索 jar 包的顺序

1、本地仓库,如果本地仓库中含有 _remote.repositories 文件,则会去文件中写的远程仓库地址进行拉取;
2、maven settings profile中的repository;
3、pom.xml中profile中定义的repository;
4、pom.xml中的repositorys(定义多个repository,按定义顺序找);
5、mirror

参考文章

Maven 生命周期

maven中使用scope= import

Maven配置文件解析

*Maven之setting.xml解析

MAVEN snapshot快照和release发布库的区别、作用

Apache Maven Site Plugin概述

聊聊 maven 的 snapshot 和 metadata

maven-metadata.xml文件的作用

极客学院 maven 教程

附录

附1:


    
    
        
        
        
        
        
        
        
        
    
    
    4.0.0
    
    asia.banseon
    
    banseon-maven2
    
    jar
    
    1.0-SNAPSHOT
    
    banseon-maven
    
    http://www.baidu.com/banseon
    
    A maven project to study maven.
    
    
        
        
    
    
    
        
        jira
        
        http://jira.baidu.com/banseon
    
    
    
        
        
        
        
        
        
            
            
                
                
                
                
                
                
                
                
                
                
                
                
Demo [email protected] [email protected] [email protected] http:/hi.baidu.com/banseon/demo/dev/ HELLO WORLD banseon [email protected] Project Manager Architect demo http://hi.baidu.com/banseon No -5 Apache 2 http://www.baidu.com/banseon/LICENSE-2.0.txt repo A business-friendly OSS license scm:svn:http://svn.baidu.com/banseon/maven/banseon/banseon-maven2-trunk(dao-trunk) scm:svn:http://svn.baidu.com/banseon/maven/banseon/dao-trunk http://svn.baidu.com/banseon demo http://www.baidu.com/banseon ...... ...... Windows XP Windows x86 5.1.2600 mavenVersion 2.0.3 /usr/local/hudson/hudson-home/jobs/maven-guide-zh-to-production/workspace/ /usr/local/hudson/hudson-home/jobs/maven-guide-zh-to-production/workspace/ ...... ...... ...... ...... ...... ...... banseon-repository-proxy banseon-repository-proxy http://192.168.1.169:9999/repository/ default ...... org.apache.maven maven-artifact 3.8.1 jar test spring-core org.springframework true ...... banseon-maven2 banseon maven2 file://${basedir}/target/deploy banseon-maven2 Banseon-maven2 Snapshot Repository scp://svn.baidu.com/banseon:/usr/local/maven-snapshot banseon-site business api website scp://svn.baidu.com/banseon:/var/www/localhost/banseon-web

你可能感兴趣的:(Maven 那点不为人知的事)