maven实践–你所需要精通的maven

基本概念

是什么?

Maven是一个强劲的Java项目构建工具。

什么是构建工具?

构建工具是将软件项目构建相关的长河自动化的工具。构建一个软件项目一般包含以下一个或三个过程:

  1. 转变源码(如若项目采取自动生成源码);
  2. 从源码生成项目文档;
  3. 编译源码;
  4. 运转单元测试
  5. 将编译后的代码打包成JAR文件或者ZIP文件;
  6. 将打包好的代码安装到服务器、仓库或者其他的地方;
  7. 讲述项目间的借助关系

多少项目可能需要更多的进程才能形成构建,这个过程相似也足以组成到构建工具中,因而它们也得以实现自动化。

自动化构建过程的利益是将手动构建过程中犯错的风险降到最低。而且,自动构建工具平日要比手动执行同一的构建过程要快。

着力概念:POM文件(POM project object mode项目对象模型)

POM文件是以XML文件的样式公布项目标资源,如源码、测试代码、依赖(用到的外表Jar包)等。

pom紧要组成部分:
图片 1

简单来说运行

当你安装好了Maven,并且在档次的根目录下创办了POM文件,可以在类型上运行Maven了。

mvn clean install

该命令首先执行clean构建周期,删除Maven输出目录中已编译的类文件,然后执行install构建阶段。

maven深远举办

构建生命周期

Maven中置放了三个构建生命周期:default,clean和site。default生命周期处理工程的部署,clean生命周期处理工程的清理,而site生命周期则承担创造工程的站点文档。

packaging直接影响Maven的构建生命周期。

在Maven 3中,其可用的打包类型如下:

  1. jar,默认类型
  2. war
  3. ejb
  4. ear
  5. rar
  6. par
  7. pom
  8. maven-plugin

一经想三回打包三个档次,可利用聚合类型pom,它一般由一个父模块和多少身材模块组成。

<packaging>pom</packaging>

<modules>
    <module>zy-service-consumer</module>
    <module>zy-eureka-server</module>
    <module>zy-zipkin-service</module>
    <module>zy-hystrix-dashboard</module>
</modules>

构建生命周期是由阶段组成的

多少个构建生命周期都是由一多样不同的构建阶段组成,每一个构建阶段代表了生命周期的一个阶段。

以default生命周期为例,它是由以下的阶段组成

  • validate – 验证该项目是否科学,所有必要的音信都是可用的
  • compile – 编译工程源码
  • test –
    使用一个老少咸宜的单元测试框架测试编译的源代码。那一个测试的代码不会被打包或安排到花色中
  • package – 将编译的代码打包成它揭穿的格式,例如JAR
  • integration-test –
    如若必要的话,该命令会将工程处理并配备在一个合一测试运行的条件中
  • verify – 运行任何检查以验证该包是否可行,是否合乎质料标准
  • install – 将工程打包安装到本地仓库中,以便地面其他体系得以拓展倚重
  • deploy –
    在合龙或公布环境中,将最后工程打包复制到远程仓库中,用于与此外开发人士和系列共享

mvn deploy
它不仅执行指定的构建阶段,而且会执行指定构建阶段之前的每一个阶段。因此,执行

构建阶段选拔的构建插件

mvn install


[INFO] ------------------------------------------------------------------------
[INFO] Building zy-zeromq 1.0.0
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ zy-zeromq ---
[INFO] 
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ zy-zeromq ---
[INFO] 
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ zy-zeromq ---
[INFO] 
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ zy-zeromq ---
[INFO] 
[INFO] --- maven-surefire-plugin:2.18.1:test (default-test) @ zy-zeromq ---
[INFO] 
[INFO] --- maven-jar-plugin:2.6:jar (default-jar) @ zy-zeromq ---
[INFO] 
[INFO] --- maven-install-plugin:2.5.2:install (default-install) @ zy-zeromq ---

(查看完整的生命周期阶段列表,请参见生命周期参考

仓库

仓库只分为两类:本地仓库和长距离仓库。

当Maven遵照坐标寻找构建的时候,首先会翻动本地仓库,假若当地仓库存在此部件,则一直利用;如若当地仓库不存在此部件,或者需要查阅是否有改进的构件版本,Maven就会到长途仓库查找,发现需要的预制构件后,将其下载到本地仓库再使用。如若地点仓库和长途仓库都不设有需要的预制构件,则报错。

图片 2

私服

私服的补益:节约外网的带宽,加速Maven的构建,方便部署第三方构件,稳定等

图片 3

布置到长途仓库

将本项目jar包上传到私服、远程仓库,供项目组或其外人使用。配置如下:

pom.xml
<distributionManagement>
    <repository>
        <id>thirdparty</id>
        <name>3rd party</name>
        <url>http://192.168.100.103:8081/nexus/content/repositories/thirdparty/</url>
    </repository>
</distributionManagement>

settigns.xml配置认证
<servers>
    <server>
        <id>thirdparty</id>
        <username>repo-user</username>
        <password>repo-psw</password>
    </server>
</servers>


mvn命令:
本地仓库 的更新
mvn  clean package install 
远程 仓库 的更新
mvn clean package deploy

如果编译出问题时,可以执行如下命令
mvn clean install -e -U
-e详细异常,-U强制更新 

为了加快下载,可以安排部分镜像mirror。

依赖

凭借传递性

  1. 子项目可以继续父项目标依靠
  2. 类型A倚重项目B,项目A–>项目B,项目B中的倚重也会被插手到品种A中。

鉴于倚重的传递性,导致项目中设有六个同名的jar包,存在jar包争辨等。maven提供的以下机制来化解这几个题目:

借助于调解原则

走动Maven
2.0.9上马,POM中凭借讲明的一一决定了哪个版本会被运用,也叫作”第一扬言原则”。

依靠管理

在多模块应用中,可能四个子项目会有一起的倚重。

在顶层的pom中指定看重项的本子,以便让所有的子项目使用同一版本。dependency
management只是倚重的一个宣称,子项目需显式引用,但绝不指定版本号。

父项目pom
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>${spring-cloud.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>


子项目pom,需显式引用依赖,但不用指定版本号。
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>

依靠范围

  • compile 默认的scope,表示 dependency
    都得以在生命周期中应用。而且,那些dependencies
    会传递到依靠的品种中。适用于拥有阶段,会趁着项目同步发表
  • provided 跟compile相似,可是讲明了dependency
    由JDK或者容器提供,例如Servlet AP和一部分Java EE APIs。这么些scope
    只可以功能在编译和测试时,同时没有传递性。

    <dependency>
    <groupId>org.apache.storm</groupId>
    <artifactId>storm-core</artifactId>
    <version>1.1.1</version>
    <scope>provided</scope>
    </dependency>
    
  • runtime
    代表dependency不效用在编译时,但会效用在运转和测试时,如JDBC驱动,适用运行和测试阶段。

  • system 跟provided
    相似,可是在系统中要以外部JAR包的款式提供,maven不会在repository查找它。
  • import(Maven2.0.9及以上)
    import范围只适用于pom文件中的
  • test
    范围讲明使用此倚重范围的依赖性,只在编译测试代码和运作测试的时候需要,应用的正常运行不需要此类倚重。

借助排除

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.apache.tomcat</groupId>
            <artifactId>tomcat-jdbc</artifactId>
        </exclusion>
    </exclusions>
</dependency>
  • 小技巧:一般在编译时类找不到,可是其实存在jar争执情形时。在idea中装置Maven
    Helper插件,按照jar名称搜索,定位到具体的借助,在依靠中排除争辨jar包。

可选倚重

可选的依赖工作规律

Project-A -> Project-B
地点的图表示项目A倚重于项目B,当A在它的POM文件中把B声明为一个可选的借助,他们的涉及依旧没有更改。仅仅就像几次正常的构建,在这一次构建中,项目B将会被添加进classpath。

Project-X -> Project-A
然则当一个其他的品类(项目X)在它的POM文件中宣示项目A为一个依赖,这么些可选的借助就发挥效用了。你将会小心到项目X的classpath不会蕴藏项目B:为了把B包含进项目X的classpath,你需要在您的POM文件中向来注脚。

例子:

有一个名为X2的项目,那么些序列和hibernate有一些好像的效果,帮忙广大数据库驱动/看重,比如说MySQL,postgre,oracle等。为了构建X2,所有的这么些倚重都是必须的,然则对于你的体系以来却不是必须的,所以对于X2把那个看重阐明为可选的是丰富实用的,不论什么时候当你在POM文件中把X2讲明为一个平素看重的时候,所有被X2襄助的驱动不会自动的被含有进你的花色的classpath,你需要平昔讲明你将要利用的数据库的依赖/驱动。

自定义打包maven-assembly-plugin

在运作mapreduce/storm时,一般是以jar包形式运行,每个jar包中凭借的jar的包,可以运用maven-assembly-plugin。

<build>
    <plugins>
        <plugin>
            <artifactId>maven-assembly-plugin</artifactId>
            <configuration>
                <appendAssemblyId>false</appendAssemblyId>
                <descriptors>
                    <descriptor>assembly.xml</descriptor>
                </descriptors>
                <finalName>${project.artifactId}-${project.version}</finalName>
                <attach>false</attach>
            </configuration>
            <executions>
                <execution>
                    <id>make-assembly</id>
                    <phase>package</phase><!-- 绑定到package生命周期阶段上 -->    
                    <goals>
                        <goal>single</goal><!-- 只运行一次 --> 
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

assembly.xml

<!--是否生成和项目名相同的根目录-->
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
    <fileSet>
        <directory>${project.basedir}/target/classes</directory>
        <outputDirectory>.</outputDirectory>
    </fileSet>
    <!--<fileSet>
        <directory>${project.basedir}/src/main/resources</directory>
        <outputDirectory>./</outputDirectory>
    </fileSet>-->
</fileSets>
<dependencySets>
    <dependencySet>
        <!--是否把本项目添加到依赖文件夹下-->
        <useProjectArtifact>false</useProjectArtifact>
        <outputDirectory>/lib</outputDirectory>
        <!--<excludes>
            <exclude>org.apache.storm:storm-core</exclude>
        </excludes>-->
    </dependencySet>
</dependencySets>

任何大规模配置模式

<configuration>
    <descriptorRefs>
        <descriptorRef>jar-with-dependencies</descriptorRef>
    </descriptorRefs>
    ...
</configuration>
这种方式打出的包是fat jar,也就是把依赖的jar包全部解压成class文件后,再与自己的代码打成一个jar包。

maven assembly

命令

  1. mvn clean 清除目标目录中的生成结果
  2. mvn package 依照项目转移 jar 文件,打包在此之前会展开编译,测试
  3. mvn install在本地 Repository 中安装 jar

跳过测试类 : -Dmaven.test.skip=true
下载jar包源码: -DdownloadSource=true
下载javadocs: -DdownloadJavadocs=true

Archrtype

原型(Archetype)是一个Maven工程模板工具包。

maven-archetype-quickstart用得相比多。

maven vs gradle

  • maven和gradle的可比与利用
    看来,gradle相相比较于maven有很打的油滑,方今gradle的使用者越来越多。而鉴于maven在此以前处于主流,并且在一些地点maven较gradle还有部分独到之处,所以maven和gradle并存。在github上多数可以的开源项目及其时提供maven和gradle二种充分依赖的点子。

参考文献


tips:本文属于自己学习和举办进程的笔录,很多图和文字都粘贴自网上作品,没有阐明引用请见谅!如有任何问题请留言或邮件公告,我会即刻过来。

网站地图xml地图