收藏文章Linux

Maven小结

2019-10-02  本文已影响0人  Arvesynden

什么是Maven?

Maven是一个项目管理和综合工具,Maven使用标准的目录结构和默认构建生命周期。提供了开发人员构建一个完整的生命周期框架,开发团队可以自动完成该项目的基础设施建设。

简单来说,Maven能简化和标准化项目建设过程。

Maven项目的结构和内容是在一个XML文件中声明,pom.xml的项目对象模型(POM),这是整个Maven系统的基本单元。

Maven的作用:

1、下载jar包:只要添加相应配置,会自动下载相应jar包。

2、下载依赖:只要配置的jar包所依赖的其他jar包都会被maven自动下载下来

3、热部署:在web项目已经运行的时候,修改代码的能直接被web服务器所接受,就不需要重启服务器了,或者重新部署代码,而且可以直接通过maven 打包war或者jar项目。

Maven目录结构:

src/main:存放主程序

src/main/java:存放java源代码

src/main/resources::存放框架或其他工具的配置文件

src/test/java:存放测试程序

src/test/resources:存放测试的配置文件

target:执行 maven install命令时自动生成的。

pom.xml:Maven的核心配置文件

Maven环境配置

Maven如何管理jar包

什么是坐标?

①、数学中的坐标

    在平面上,使用 X 、Y 两个向量可以唯一的定位平面中的任何一个点

    在空间中,使用 X、Y、Z 三个向量可以唯一的定位空间中的任意一个点

②、Maven 中的坐标

    俗称 gav:使用下面三个向量子仓库中唯一定位一个 Maven 工程

    在项目中的 pom.xml 文件中,我们可以看到下面gav的定义:

              1、groupid:公司或组织域名倒序 

      <groupid>com.ys.maven</groupid>

    2、artifactid:模块名,也是实际项目的名称

      <artifactid>Maven_05</artifactid>

    3、version:当前项目的版本

      <version>0.0.1-SNAPSHOT</version>

③、Maven 坐标和仓库,jar 包的关系

1、仓库       

        maven项目使用任何一个构件的方式都是完全相同的,maven可以在某个位置统一存储所有maven共享的构件,这个统一的位置便是仓库。仓库是Maven 用来存放 jar 包的地方。

       仓库只分为两类:本地仓库和远程仓库。当maven根据坐标寻找构件的时候,它首先会查看本地仓库,如果本地仓库存在,直接使用;如果本地仓库不存在,需要查看是否有更新的构件版本,maven就会去远程仓库寻找,发现需要的构件之后,下载到本地仓库再使用。如果都没有找到,maven会报错。

2、关系

      可简单理解为:maven通过坐标从仓库中寻找构件(即依赖的jar包)。

Maven生命周期

完整的项目构建过程包括:清理——>编译——>测试——>打包——>集成测试——>验证——>部署。

maven中定义三套独立的生命周期:分别包括clean、default、site,这三套生命周期是相互独立的,每个生命周期又包含一些阶段,各个生命周期的阶段是有顺序的,且后面的阶段依赖前面的阶段,执行每个阶段时,其前面的阶段会依次顺序执行,但不会触发另外两套生命周期的任何阶段。

1、clean:目的是来清理项目,它又分为三个阶段。

pre-clean执行清理前的工作

clean清理上一次构建生成的所有文件

post-clean执行清理后的文件

2、default:目的是来构建项目(生命周期中最核心,包含了构建项目时所要执行的步骤),阶段比较多,常用阶段有以下几种。

例如:compile test package install,默认都是default这个生命周期中的。

3、site:生成项目的站点,会根据pom种的信息,自动生成一个站,它又分为以下几个阶段。

pre-site:在生成项目站点前要完成的工作。

site:生成项目的站点文档。

post-site:在生成项目站点后要完成的工作。

site-deploy:发布生成的站点到服务器上。

       在maven中,只要在同一个生命周期,你执行后面的阶段,那么前面的阶段也会被执行,而且不需要额外去输入前面的阶段。如,mvn package;在运行package命令之前,并没有compile和test,但当我们运行package之后,它的compile和test是依次执行的,也就是运行package这个阶段时,compile和test会自动的运行。

什么是依赖?

每当我们需要使用某个框架时,比如 SpringMVC,那么我们需要导入相应的 jar 包,但是手动导入包的时候,往往会漏掉几个 jar 包,那么在使用该框架的时候系统就会报错。那么我们就说导入的包与未导入的包存在依赖关系。而使用 Maven,我们只需要在 pom.xml文件中进行相应的配置,它就会帮助我们自动管理 jar 包之间的依赖关系。

以 Junit 为例,在 pom.xml 文件中进行详细而完整的配置。

<project>     

    <dependencies>

        <dependency>

            <groupId>junit</groupId>     

            <artifactId>junit</artifactId>     

            <version>3.8.1</version>

            <type>...</type>

            <scope>...</scope>

            <optional>...</optional>

            <exclusions>     

                <exclusion>     

                  <groupId>...</groupId>     

                  <artifactId>...</artifactId>     

                </exclusion>

          </exclusions>     

        </dependency>        

      </dependencies>     

</project>

     ①、dependencies:一个 pom.xml 文件中只能存在一个这样的标签。用来管理依赖的总标签。

  ②、dependency:包含在dependencies标签中,可以有无数个,每一个表示一个依赖

  ③、groupId,artifactId和version:依赖的基本坐标,对于任何一个依赖来说,基本坐标是最重要的,Maven根据坐标才能找到需要的依赖。

  ④、type:依赖的类型,对应于项目坐标定义的packaging。大部分情况下,该元素不必声明,其默认值是jar。

  ⑤、scope:依赖的范围,默认值是 compile。

  ⑥、optional:标记依赖是否可选。

  ⑦、exclusions:用来排除传递性依赖。

依赖的范围Scope

 <scope>...</scope>标签的可选配置:compile、test、provided、runtime、system、import

1)编译依赖范围(compile),该范围就是默认依赖范围,此依赖范围对于编译、测试、运行三种classpath都有效,如log4j。

2)测试依赖范围(test),顾名思义就是针对于测试的,使用此依赖范围的依赖,只对测试classpath有效,在编译主代码和项目运行时,都将无法使用该依赖,最典型的例子就是 Junit。

3)已提供依赖范围(provided),使用该依赖范围的maven依赖,只对编译和测试的classpath有效,对运行的classpath无效,典型的例子就是servlet-api。

4)运行时依赖范围(runtime),使用该依赖范围的maven依赖,只对测试和运行的classpath有效,对编译的classpath无效,典型例子就是JDBC的驱动实现。

5)系统依赖范围(system),该依赖与classpath的关系与 provided依赖范围完全一致,但是系统依赖范围必须通过配置systemPath元素来显示指定依赖文件的路径,此类依赖不是由maven仓库解析的,而且往往与本机系统绑定,可能造成构件的不可移植,因此谨慎使用,systemPath元素可以引用环境变量。

6)导入依赖范围(import),该依赖范围不会对三种classpath产生影响,该依赖范围只能与dependencyManagement元素配合使用,其功能为将目标pom文件中dependencyManagement的配置导入合并到当前pom的dependencyManagement中。

依赖传递

举例:古惑仔电影中,山鸡和南哥混,南哥和B哥混,对于山鸡而言就间接和B哥混了,换成程序而言,山鸡依赖南哥,南哥依赖B哥,山鸡就就依赖传递B哥了。

案例:

描述:新建3个maven项目,选择quickstart模板,第一个Group Id为com.hongxing,Artifact Id为hongxing-bge,Package为默认的,第二个Group Id为com.hongxing,Artifact Id为hongxing-nange,第三个Group Id为com.hongxing,Artifact Id为hongxing-shanji。

步骤1:南哥依赖于B哥,南哥的pom.xml中进行配置,引入B哥的依赖,需要知道B哥的坐标,然后编译一下南哥,Maven——>Maven build(在Goals:compile)。

南哥的maven项目首先会到本地仓库中进行查找B哥的jar包,如果本地仓库中没有,则会从远程中央仓库中下载,如果远程中央仓库中没有,则会报错,我们先将B哥进行打包,Maven——>Maven build(Goals:clean package),然后再将B哥安装到本地仓库中Maven——>Maven build(install),它依然会编译,并且会测试一遍,并且安装到指定的仓库中,接下来再对南哥进行编译Maven——>Maven build(clean compile),这样南哥就构建成功了。

步骤2:山鸡依赖于南哥,首先,要打包南哥的maven项目,并进行安装到本地仓库中Maven——>Maven build(clean install),依旧要找到南哥的坐标,然后编译一下山鸡Maven——>Maven build(compile)

依赖具有传递性,山鸡的maven项目并没有依赖B哥,B哥的依赖缺自动的加入到了山鸡的依赖目录里。

排除依赖:依赖南哥的<dependency>标签中添加<exclusions><exclusion>B哥的坐标<exclusions><exclusion>

举例:山鸡只听从南哥的吩咐,不听其他人的吩咐,将B哥的依赖从山鸡的maven项目依赖中排除。

依赖冲突

如果有A(南哥)和B(B哥)依赖了一个不同版本相同的构件(commons-io),那么对于依赖于AB的C(山鸡哥)来说,它究竟依赖于A和B的哪一个版本的构件,这里有两条原则。

1.短路优先

   A->B->C->X(jar)

   A->D->X(jar) (优先用这个X)

2.先申明先优先

如果路径长度相同,则谁先声明,先解析谁

maven聚合和继承

maven聚合:如果想在maven中将多个项目进行install,将其安装到本地仓库中,必须对其依次执行install命令,maven中有一种方式可以将其放到一起运行,这种方式称为聚合。

案例:将山鸡、南哥、B哥聚合到本地仓库中,这里需要新建一个maven项目,依旧使用quickstart模板,Group Id为com.hongxing,Artifact Id为hongxing-aggreation,它作为其他pom的容器,需要修改它的pom的<package>为pom</package>,然后使用<modules><module>B哥的maven项目名</module><module>南哥的maven项目名</module><module>山鸡的maven项目名</module></modules>,然后右键hongxing-aggreation的Maven——>Maven build,Goals输入clean install控制台输出结果为三次构建,第一次生成B哥的jar,并且将其安装到本地仓库中,第二次生成南哥的jar,并且将其安装到本地仓库中,第三次生成山鸡的jar,并且将其安装到本地仓库中。

继承:三个maven项目中都有一个共同的特点,就是都使用了junit,并且在每个项目的pom.xml中,都对其进行了配置,比如说b哥的maven使用了如下图,这样就出现了很多重复的地方,其实maven中可以想java中一样,将其共同的特性封装成一个父类,所以新建一个maven项目,Group Id为com.hongxing,Artifact Id为hongxing-parent,然后修改它的pom.xml,要将标签放置在标签里,如果使用这个标签对依赖进行管理,它并不会在这个项目中运行,也可以将junit的版本号提取出来,在外面定义一个属性,并在该属性里通过设置junit的版本号,这样就可以在中的中像使用EL表达式那样来调用它,${junit.version},最后将它的改成pom,然后打开B哥的pom让其继承pom,这里就可以将junit的版本号进行删除,也可以删除掉,这里要使用到标签,然后引入我们的parent的maven的坐标,这样junit已经从父类parent,也就是pom中继承过来了。

Maven创建web项目

Maven创建web项目

Maven VS Ant

相同点:

           都是项目构建管理工具。

不同点有:

           1. Maven约定了目录结构,而Ant没有。

           2. Maven是声明式的,用pom.xml文件;而Ant是程序式的,构建过程需要自定义,用builder.xml.

           3. Maven是有生命周期的,而Ant没有。

           4. Maven内置依赖管理和Repository来实现依赖的管理和统一存储;而Ant没有。Maven第一次install的时候会把依赖的jar包和构件从远处库(又叫中央库,http://repol.maven.org/maven2,统一存储maven可以解释的文件资源)下载到本地库(先从本地仓库找)。Maven还可以管理传递依赖。

           5.Maven配置比较简单,有很多的约定、规范、标准,可以用较少的代码干更多的事;而Ant配置比较麻烦,需要配置整个构建的过程(但Ant配置灵活)。

上一篇 下一篇

猜你喜欢

热点阅读