美文网首页Maven
Maven学习笔记

Maven学习笔记

作者: GeekerLou | 来源:发表于2019-12-01 12:14 被阅读0次

    常用指令

    maven 命令的格式为 mvn [plugin-name]:[goal-name],可以接受的参数如下。

    -D 指定参数,如 -Dmaven.test.skip=true 跳过单元测试;
    -P 指定 Profile 配置,可以用于区分环境;
    -e 显示maven运行出错的信息;
    -o 离线执行命令,即不去远程仓库更新包;
    -X 显示maven允许的debug信息;
    -U 强制去远程更新snapshot的插件或依赖,默认每天只更新一次。

    # maven 打包:
    mvn package
    
    # 编译源代码: 
    mvn compile
    
    # 编译测试代码:
    mvn test-compile
    
    # 运行测试:
    mvn test
    
    # 打版本
    mvn versions:set -DnewVersion=1.3.3-SNAPSHOT
    
    # 显示maven依赖树:
    mvn dependency:tree
    
    # 创建maven项目
    mvn archetype:create 
    
    # 指定 group: 
    -DgroupId=packageName 
    
    # 指定 artifact:
    -DartifactId=projectName
    
    # 创建web项目:
    -DarchetypeArtifactId=maven-archetype-webapp  
    
    # 创建maven项目:
    mvn archetype:generate
    
    #验证项目是否正确:
    mvn validate
    
    # 只打jar包:
    mvn jar:jar
    
    # 生成源码jar包:
    mvn source:jar
    
    # 产生应用需要的任何额外的源代码:
    mvn generate-sources
    
    
    
    # 运行检查:
    mvn verify
    
    # 清理maven项目:
    mvn clean
    
    # 生成eclipse项目:
    mvn eclipse:eclipse
    
    # 清理eclipse配置:
    mvn eclipse:clean
    
    # 生成idea项目:
    mvn idea:idea
    
    # 安装项目到本地仓库:
    mvn install
    
    # 发布项目到远程仓库:
    mvn:deploy
    
    # 在集成测试可以运行的环境中处理和发布包:
    mvn integration-test
    
    # 显示maven依赖列表:
    mvn dependency:list
    
    # 下载依赖包的源码:
    mvn dependency:sources
    
    # 安装本地jar到本地仓库:
    mvn install:install-file -DgroupId=packageName -DartifactId=projectName -Dversion=version -Dpackaging=jar -Dfile=path
    

    本地仓库与远程仓库

    image.png

    关于<dependency>的使用

    image.png image.png

    其实这个标签揭示了jar的查找坐标:groupId、artifactId、version。

    version分为开发版本(Snapshot)和发布版本(Release),那么为什么要分呢?

    在实际开发中,我们经常遇到这样的场景,比如A服务依赖于B服务,A和B同时开发,B在开发中发现了BUG,修改后,将版本由1.0升级为2.0,那么A必须也跟着在POM.XML中进行版本升级。过了几天后,B又发现了问题,进行修改后升级版本发布,然后通知A进行升级...可以说这是开发过程中的版本不稳定导致了这样的问题。

    Maven,已经替我们想好了解决方案,就是使用Snapshot版本,在开发过程中B发布的版本标志为Snapshot版本,A进行依赖的时候选择Snapshot版本,那么每次B发布的话,会在私服仓库中,形成带有时间戳的Sn[图片上传中...(image.png-107d99-1575173093654-0)]
    apshot版本,而A构建的时候会自动下载B最新时间戳的Snapshot版本!

    如何解决版本冲突

    image.png

    依赖的版本?

    首先来说,对于Maven而言,同一个groupId同一个artifactId下,只能使用一个version!

    根据上图的依赖顺序,将使用1.2版本的jar。

    现在,我们可以思考下了,比如工程中需要引入A、B,而A依赖1.0版本的C,B依赖2.0版本的C,那么问题来了,C使用的版本将由引入A、B的顺序而定?这显然不靠谱!如果A的依赖写在B的依赖后面,将意味着最后引入的是1.0版本的C,很可能在运行阶段出现类(ClassNotFoundException)、方法(NoSuchMethodError)找不到的错误(因为B使用的是高版本的C)!

    这里其实涉及到了2个概念:依赖传递(transitive)、Maven的最近依赖策略。

    依赖传递:如果A依赖B,B依赖C,那么引入A,意味着B和C都会被引入。

    Maven的最近依赖策略:如果一个项目依赖相同的groupId、artifactId的多个版本,那么在依赖树(mvn dependency:tree)中离项目最近的那个版本将会被使用。(从这里可以看出Maven是不是有点小问题呢?能不能选择高版本的进行依赖么?据了解,Gradle就是version+策略)

    现在,我们可以想想如何处理依赖冲突呢?

    想法1:要使用哪个版本,我们是清楚的,那么能不能不管如何依赖传递,都可以进行版本锁定呢?

    使用<dependencyManagement> 来实现维护所有子模块版本的一致性。

    想法2:在依赖传递中,能不能去掉我们不想依赖的?

    使用<exclusions> [在实际中我们可以在IDEA中直接利用插件帮助我们生成]

    想法3:既然是最近依赖策略,那么我们就直接使用显式依赖指定版本,那不就是最靠近项目的么?Maven继承与聚合,这个你需要掌握。

    想法4:引入依赖的最佳实践,提前发现问题

    在工程中,我们避免不了需要加一些依赖,也许加了依赖后运行时才发现存在依赖冲突在去解决,似乎有点晚!那么能不能提前发现问题呢?

    如果我们新加入一个依赖的话,那么先通过mvn dependency:tree命令形成依赖树,看看我们新加入的依赖,是否存在传递依赖,传递依赖中是否和依赖树中的版本存在冲突,如果存在多个版本冲突,利用上文的方式进行解决!

    相关文章

      网友评论

        本文标题:Maven学习笔记

        本文链接:https://www.haomeiwen.com/subject/lvjzwctx.html