• 《Maven实战》笔记


    maven是什么

    maven是

    • 构建工具
    • 依赖关系工具
    • 项目信息管理工具

    而JAVA世界的ant只是一个构建工具,不具备依赖管理的功能,需要配合使用ivy进行依赖管理。

    maven的安装

    下载maven,配置环境变量。
    升级的技巧:使用符号链接,环境变量指向符号链接,升级的时候修改符号链接即可。

    maven使用入门

    手动搭建maven项目

    • 编写pom
    • 编写主代码和测试代码

    使用ArcheType创建maven项目骨架

    命令如下
    mvn archetype:generate
    实际上上述命令的完整格式是:
    mvn groupId:artifactId:version:goal
    即运行的是archetype插件的generate目标。
    也可以为自己的项目开发archetype。

    编译,测试,打包,安装,运行

    • 编译: mvn clean compile
    • 测试:mvn clean test
    • 打包:mvn clean package
    • 安装:mvn clean install
    • 运行
      • 使用maven-shade-plugin插件生成可执行的jar.
        • pom中配置shade插件。
        • 执行 mvn clean install,重新生成jar包。
      • 运行jar包。java -jar xxx.jar

    坐标和依赖

    maven坐标的各个元素

    • groupId
    • artifactId
    • version
    • packaging:打包方式。比如jar或者war。
    • classifier:附属构件。比如javadoc和源代码。

    依赖的元素

    • groupId
    • artifactId
    • version
    • type:同坐标中的packaging。默认为jar。
    • scope:依赖范围
    • optional
    • exclusions

    依赖范围

    三种classpath:编译classpath,测试classpath,运行classpath。

    • compile:对编译、测试、运行三种classpath都有效。
    • test:只对测试classpath有效。比如JUnit。
    • provided:编译和测试classpath有效,运行classpath无效。比如servlet API。
    • runtime:测试和运行classpath有效,编译classpath无效。比如JDBC驱动实现。
    • system:与provided一致。只是这种情况必须显示指定依赖文件的路径,这样就和本机系统绑定了,使得构建不具有移植性,慎用。
    • import:不会对三种classpath产生影响。

    依赖范围不仅可以控制依赖与三种classpath的关系,还对传递性依赖产生影响。

    传递性依赖

    传递性依赖机制:maven会解析各个直接依赖的pom,将那些必要的间接依赖以传递性依赖的形式引入到当前项目中。(我们只需要关心项目的直接依赖)

    maven会自动解析所有项目的直接依赖和传递性依赖,确保每个构件只有唯一的版本在依赖中存在。最后解析后的这些依赖被称为已解析依赖
    相关命令
    查看已解析依赖:mvn dependency:list
    依赖树:mvn dependency:tree
    分析依赖:mvn dependency:analyze

    生命周期和插件

    生命周期和阶段

    maven对构建过程进行了抽象,被称为生命周期。生命周期本身不做具体任务,实际的任务由插件完成。这是一种模板方法模式。

    生命周期包含一些阶段(phase),这些阶段有前后依赖关系,后面的阶段依赖前面的阶段。可以定义多个生命周期,生命周期之间彼此是独立的,不存在依赖关系。

    Maven拥有三套独立的生命周期,分别是clean、default和site。

    • clean生命周期的目的是清理项目。
    • default生命周期的目的是构建项目。
    • site生命周期的目的是建立项目站点。

    clean生命周期

    包含三个阶段:

    • pre-clean
    • clean
    • post-clean

    defalut生命周期

    包含的阶段太多,详情 Introduction to the Build Lifecycle

    site生命周期

    • pre-site
    • site
    • post-site
    • site-deploy

    命令行与生命周期的关系

    常用的mvn clean compile命令实际上调用的是clean生命周期的clean阶段和default生命周期的compile阶段。

    插件和插件目标

    对于插件而言,为了能够复用代码,它能够执行多个任务,实现多个功能,这些功能聚集在一个插件里,每个功能就是一个插件目标。比如maven-dependency-plugin插件,它可以分析项目依赖,列出项目的依赖树,找出无用依赖。

    通常写法是:插件:插件目标

    插件绑定

    将生命周期中的阶段和插件目标绑定。
    那么在命令行输入生命周期的阶段,则对应的插件目标就会执行相应的任务。

    Q:是否可以直接在命令行中直接指定执行某个插件目标'???
    A:可以。

    多个插件目标可以绑定到同一个阶段。

    总结

    A Build Lifecycle is Made Up of Phases
    A Build Phase is Made Up of Plugin Goals

    聚合和继承

    聚合

    解决如下需求:想要用一条命令一次性构建多个项目(模块)。
    这就是maven聚合(多模块)特性。
    方法:增加一个聚合模块,其中的pom.xml中的packaging为pom。

    聚合模块和其他模块的目录关系

    不一定是父子关系,也可以是平行的目录结构。

    继承

    目的:解决多模块maven项目的配置重复问题。
    方法:增加一个父模块,在父pom中声明一些配置供子pom继承。

    父模块和聚合模块一般同时存在多模块maven项目中。父模块也要在聚合模块中的modules标签中配置。

    可继承的pom元素

    • groupId
    • version
    • dependencies
    • dependencyManagement
    • build
    • repositories
    • properties
    • ...

    依赖管理

    可以将一些依赖放到父模块的dependencies元素中,这样子类就无需配置了。但会存在一个问题:所有的子模块都会依赖父模块dependencies元素中声明的依赖,即使一些子模块并不需要这些依赖。

    解决方法:
    在父模块中使用dependencyManagement元素声明依赖,这些依赖不为直接被子模块继承。子模块若要继承父模块dependencyManagement中声明的某个依赖的话,则需要在子模块中的dependencies元素中重新声明(只需要配置groupId和artifactId即可)。
    虽然这种方式不会大幅度的减少配置,但是由于在父模块的pom中统一申明了依赖的版本,可以避免在子模块中使用的依赖版本不一致的情况。

    import依赖范围

    名为import的依赖范围只在dependencyManagement元素下采用效果。其作用是将目标pom中的dependencyManagement配置导入并合并到当前pom中的dependencyManagement元素中。

    插件管理

    pluginManagement和dependencyManagement类似。

    聚合与继承的关系

    目的不同:

    • 聚合是为了方便快速构建项目。
    • 继承是为了消除重复配置。

    聚合模块 vs. 被聚合模块:聚合模块知道被聚合模块,但被聚合模块不知道聚合模块的存在。
    父模块 vs. 子模块:父模块不知道那些子模块继承自它,但子模块都知道自己的父模块。

    相同点:父模块和聚合模块都没有实际内容,并且两者的pom中的packaging都必须是pom。

    实际项目中,会发现一个pom既是父pom,又是聚合pom,这么做主要是为了方便。

    约定优于配置

    所有的pom都继承自超级POM。
    对于Maven3,超级POM在$MAVEN_HOME/lib/maven-model-builder-x.x.x.jar中的org/apache/maven/model/pom-4.0.0.xml路径下。
    对于Maven2,超级POM在$MAVEN_HOME/lib/maven-model-x.x.x-uber.jar中的org/apache/maven/pom-4.0.0.xml路径下。
    在超级POM中已经定义了源代码的路径、构建的输出路径等信息。

    反应堆

    构建一个多模块项目时,由于模块间存在继承或者聚合关系,模块间的构建是有先后关系的,整体构成一个有向无环图DAG。反应堆就是所有模块组成的一个构建结构。

    持续集成

    比如TensorFlow的持续集成:http://ci.tensorflow.org/

    使用maven构建web应用

    war文件的目录结构

    todo

    web项目的maven目录结构

    todo

    快速生成web项目的maven目录结构

    生成web项目的maven目录结构

    jetty-maven-plugin插件

    doc

          <plugin>
            <groupId>org.mortbay.jetty</groupId>
            <artifactId>jetty-maven-plugin</artifactId>
            <version>8.1.13.v20130916</version>
            <configuration>
              <webApp>
                <contextPath>/</contextPath>
              </webApp>
              <connectors>
                <connector implementation="org.eclipse.jetty.server.nio.SelectChannelConnector">
                  <port>8081</port>
                  <maxIdleTime>60000</maxIdleTime>
                </connector>
              </connectors>
            </configuration>
          </plugin>

    http://wiki.eclipse.org/Jetty/Feature/Jetty_Maven_Plugin

    使用cargo实现自动化部署

    Cargo支持两种本地部署的方式:standalone模式和existing模式。如下是standalone模式:

          <plugin>
            <groupId>org.codehaus.cargo</groupId>
            <artifactId>cargo-maven2-plugin</artifactId>
            <version>1.6.2</version>
            <configuration>
              <container>
                <containerId>tomcat8x</containerId>
                <home>D:Program Filesapache-tomcat-8.0.23</home>
              </container>
              <configuration>
                <type>standalone</type>
                <home>${project.build.directory}/tomcat8x</home>
                <properties>
                  <cargo.servlet.port>8181</cargo.servlet.port>
                </properties>
              </configuration>
            </configuration>
          </plugin>

    existing模式:

          <plugin>
            <groupId>org.codehaus.cargo</groupId>
            <artifactId>cargo-maven2-plugin</artifactId>
            <version>1.6.2</version>
            <configuration>
              <container>
                <containerId>tomcat8x</containerId>
                <home>D:Program Filesapache-tomcat-8.0.23</home>
              </container>
              <configuration>
                <type>existing</type>
                <home>D:Program Filesapache-tomcat-8.0.23</home>
                <!-- existing模式下好像无法更改端口 -->
                <!--<properties>-->
                  <!--<cargo.servlet.port>8080</cargo.servlet.port>-->
                <!--</properties>-->
              </configuration>
            </configuration>
          </plugin>

    Archetype

    Archetype Catalog

    mvn archetype:generate卡住的问题

    原因:
    执行命令mvn archetype:generate时,maven-archetype-plugin插件会先寻找archetype-catalog.xml文件,默认是从中央库中寻找该文件。由于中央库访问比较慢,所以出现卡顿现象。

    解决方案:

    • 方案(1):加上archetypeCatalog参数
      mvn archetype:generate -DarchetypeCatalog=internal

    • 方案(2):配置一个国内的镜像,加速对archetype-catalog.xml的访问。比如阿里云的maven镜像,如下:

        <mirror>
          <id>alimaven</id>
          <name>aliyun maven</name>
          <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
          <mirrorOf>central</mirrorOf>        
        </mirror>

    经验:安装maven后一定要配置一个国内的中央库镜像,比如阿里maven中央镜像库。因为后续很多mvn命令需要下载很多插件和依赖,网络不好容易导致操作失败。

    阿里云maven库列表

    下载单个构建的源码和文档

    mvn dependency:get -Dartifact=com.alibaba.citrus:citrus-webx-all:3.2.4:jar:sources
    mvn dependency:get -Dartifact=com.alibaba.citrus:citrus-webx-all:3.2.4:jar:javadoc

     

  • 相关阅读:
    CoreOS 手动更新
    阿里云ECS安装 CoreOS
    CoreOS 手动升级篇
    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!
    Microsoft.NETCore.App 版本不一致导致的运行失败
    设计模式之观察者模式
    设计模式之策略模式
    树的广度优先遍历和深度优先遍历(递归非递归、Java实现)
    设计模式之组合模式
    设计模式之外观模式
  • 原文地址:https://www.cnblogs.com/tsiangleo/p/7073166.html
Copyright © 2020-2023  润新知