Maven中的核心概念

  我们最能感受到的Maven的好处应该是它的“自动化构建”与“管理依赖关系”两大功能,下面就看围绕这两大功能的Maven中的核心概念。

1.    项目目录

  Maven 使用约定优于配置的原则 。它要求在没有定制之前,所有的项目都有如下的主要目录结构:

  

  一个 maven 项目在默认情况下会产生 JAR 文件,另外 ,编译后 的 .classe文件 会放在 ${basedir}/target/classes 下面;JAR文件会放在${basedir}/target
下面。如下图所示:

  

2.    POM (Project Object Model)

  2.1  概念介绍

    一个项目所有的配置都放置在 POM 文件中:定义项目的类型、名字,管理依赖关系,定制插件的行为等等。比如说,你可以配置 compiler 插件让它使用 java1.5 来编译。

  <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion> 

     <groupId>com.mycompany.helloworld</groupId>
     <artifactId>helloworld</artifactId>
     <version>1.0-SNAPSHOT</version>
     <packaging>jar</packaging> 

     <name>helloworld</name>
     <url>http://maven.apache.org</url> 

     <properties>
       <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
     </properties> 

     <dependencies>
       <dependency>
         <groupId>junit</groupId>
         <artifactId>junit</artifactId>
         <version>3.8.1</version>
         <scope>test</scope>
       </dependency>
     </dependencies>
    </project>    

    在 POM 中,groupId,artifactId, packaging, version 叫作 maven 坐标,它能唯一的确定一个构件。有了 maven 坐标,我们就可以用它来指定我们的项目所依赖的其他项目,插件,或者父项目。

    

    通常,大项目一般会分成几个子项目。在这种情况下,每个子项目就会有自己的 POM 文件,然后它们会有一个共同的父项目。这样只要构建父项目就能够构建所有的子项目了。子项目的 POM 会继承父项目的 POM。另外,所有的 POM都继承了一个 Super-POM。Super-POM 设置了一些默认值,比如在前面提到的默认的目录结构,默认的插件等等,它遵循了惯例优于配置的原则。如下图:

    

  2.2  Pom文件的继承与聚合

  继承

    开发中一般将公共的配置——依赖关系(包括公共的类库、插件、信息配置)放到一个父项目的pom文件,然后其它项目的pom文件,都继承该pom文件。继承的代码如下:

    

    这里需要注意,子pom文件不是一旦继承了父pom就会无条件地继承它所有的依赖关系,即插件、类库等。如果子pom想继承父pom的某个插件,只需要引入父pom中该插件的groupId与artifactId信息(不用写该插件其它的配置信息)即可。这样子pom是可以有选择性的继承它自己所需要的东西。

    

  聚合

    即大项目中一般会有一个空的Maven项目(只有pom文件,没有java代码)作为父项目,该项目的Pom文件(Modules标签中)聚合了其它子项目的Pom文件,然后只要构建父项目就能够构建所有的子项目了。

    

3.    Maven 插件

Maven的每个生命周期都有一个“插件”(目标)来保证。在前面,我们用了 mvn archetype:generate 命令来生成一个项目。那么这里的 archetype:generate 是什么意思呢?archetype是一个插件的名字,generate是目标(goal)的名字。这个命令的意思是告诉 maven 执行archetype 插件的 generate 目标。插件目标通常会写成
pluginId:goalId

  一个目标是一个工作单元,而插件则是一个或者多个目标的集合。比如说Jar插件,Compiler插件,Surefire插件等。从看名字就能知道,Jar插件包含建立Jar文件的目标, Compiler 插件包含编译源代码和单元测试代码的目标。Surefire 插件的话,则是运行单元测试。

  看到这里,估计你能明白了,mvn本身不会做太多的事情,它不知道怎么样编译或者怎么样打包。它把构建的任务交给插件去做。插件定义了常用的构建逻辑,能够被重复利用。这样做的好处是,一旦插件有了更新,那么所有的 maven 用户都能得到更新。

  Maven的插件服务非常强大,比如你想打包源代码为rar压缩格式,比如你想执行sql命令,等等,只需要找到相应的Maven插件,配置好即可使用,如下图:

  

4.    Maven 生命周期

  在前面,我们用的第二个命令是:mvn package。这里的 package 是一个maven的生命周期阶段 (lifecyclephase )。生命周期指项目的构建过程,它包含了一系列的有序的阶段 (phase),而一个阶段就是构建过程中的一个步骤。

  那么生命周期阶段和上面说的插件目标之间是什么关系呢?插件目标可以绑定到生命周期阶段上。一个生命周期阶段可以绑定多个插件目标。当 maven 在构建过程中逐步的通过每个阶段时,会执行该阶段所有的插件目标。

  maven 能支持不同的生命周期,但是最常用的是默认的Maven生命周期 (default Mavenlifecycle )。

  Maven有3套生命周期,clean、compile、site,在配置插件的时候一般都要配置插件的执行时机(即Maven的某一个生命周期),如下图:

  

  这里不一 一介绍生命周期,只介绍几个常用的:

  Clean

    pre-clean:执行一些需要在clean之前完成的工作

    clean:移除所有上一次构建生成的文件(清除Target文件夹)

    post-clean:执行一些需要在clean之后立刻完成的工作

  Compile

  process-resources:复制并处理资源文件至目标目录,准备打包

  compile:编译项目源代码

  process-test-resources:复制并处理资源文件至目标测试目录

  test-compile:编译测试源代码

  test:使用合适的单元测试框架运行测试,这些测试代码不会被打包或部署。

  package:接受编译好的代码,打包成可发布的个格式,如jar

  install:将包安装至本地仓库,以让其它项目依赖

  deploy:将最终的包复制到远程仓库,以让其它开发人员与项目共享。

  Site

    pre-site:执行一些需要在生成站点文当前完成的工作。

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

    post-site:执行一些需要在生成站点文档之后完成的工作,并未部署做准备。

    site-deploy:将生成的站点文档部署到服务器上。

5.    Maven 依赖管理

  5.1  概念介绍

    之前我们说过,maven 坐标能够确定一个项目。换句话说,我们可以用它来解决依赖关系。在 POM 中,依赖关系是在 dependencies部分中定义的。在上面的 POM 例子中,我们用 dependencies 定义了对于 junit 的依赖:

<dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies> 

    我们依赖的类库,我们都可以到Maven的中央仓库去找,例如下图找Hibernate的核心包:mvnrepository.com/search.html?query=hibernate

    

    上面的例子很简单,但是实际开发中我们会有复杂得多的依赖关系,因为被依赖的 jar 文件会有自己的依赖关系。那么我们是不是需要把那些间接依赖的 jar 文件也都定义在POM中呢?答案是不需要,因为 maven 提供了传递依赖的特性。

    所谓传递依赖是指 maven 会检查被依赖的 jar 文件,把它的依赖关系纳入最终解决的依赖关系链中。针对上面的 junit 依赖关系,如果你看一下 maven 的本地库你会发现 maven 不但下载了 junit-3.8.1.jar,还下载了它的 POM 文件。这样 maven 就能检查 junit 的依赖关系,把它所需要的依赖也包括进来。

    在 POM 的 dependencies 部分中,scope 决定了依赖关系的适用范围。我们还可以指定scope 为 provided,意思是 JDK 或者容器会提供所需的jar文件。比如说在做web应用开发的时候,我们在编译的时候需要servlet API jar 文件,但是在打包的时候不需要把这个 jar文件打在 WAR 中,因为servlet容器或者应用服务器会提供的。

    scope 的默认值是 compile,即任何时候都会被包含在 classpath 中,在打包的时候也会被包括进去。

  5.2  依赖的范围(scope)

    有如下几种:

    test:

      指测试范围有效,编译和打包时都不使用该依赖。

    compile:(为默认值)

      编译范围有效,编译和运行(打包)时都会将依赖存进去

    provided:

      测试、编译范围都有效,最后生成war包时不会加入,例如:servlet-api,编译的时候需要该文件,但是在打包的时候不需要把这个 jar 文件打在 WAR 中,因为servlet容器或者应用服务器会提供的。打进去会出现冲突。

    runtime:

   编译时不依赖,运行(打包)时依赖

    

  5.3  依赖的传递(间接依赖)

    首先,依赖是可以传递的

    

    当依赖层级相同的时候,相同的东西,会采用,近者优先。当依赖层级不同时,层级(最短)近的优先。

    

  5.4  排除依赖

    当依赖包发生冲突时,我们可以用exclusion标签排除依赖

    

6.     Maven仓 库

  6.1  概念介绍

    主要介绍3种仓库,本地仓库、私服(Nexus)、中央仓库。3者的关系如下图所示:

    

    首先,Maven本身自带一个本地仓库;然后它又为全世界的Java开发者提供了一个免费的“中央仓库”,在其中几乎可以找到任何流行的开源类库;由于中央仓库是在外网中的,如果没有私服(Nexus),本地仓库就会频繁地与中央仓库即互联网打交道,这样效率很低,所以在两者之间衍生出了一个“私服——Nexus”,私服存在于局域网中,这样本地仓库就不用频繁地与外网中的中央仓库交互,所以效率就会大大提高。

  6.2  修改本地仓库

    本地仓库的位置默认为:${user.home}/.m2/repository。例如下图:

    

    修改本地仓库位置的步骤如下:

    新建本地工厂的文件夹,如我建在,与Maven同目录下:

    

    将F:\maven\apache-maven-3.2.3\conf文件夹下的Settings.xml文件夹拷贝到上面新建的本地工厂的同级目录位置

    

    修改本地工厂同目录下的Settings.xml文件中的内容,设置本地仓库的位置为,上面新建的仓库的目录

    

    到此完成。

  6.3  中央仓库的位置

    中央仓库的位置在如下目录中:

    ${MAVEAN_HOME}\lib\maven-model-builder.jar\org\apache\maven\mode\pom.xml中,如下图:

    

    Nexus的安装与介绍在后面的文章中介绍。

7.    总结

    Maven提倡“约定优于配置”,它的项目的目录结构,测试方法的命名等都有一定的要求。

    Maven是基于Pom的,一个Maven项目所有的配置都放置在 POM 文件中:定义项目的类型、名字,管理依赖关系,定制插件的行为等等。Pom文件之间还可以继承、聚合等。

    Maven很强大,很大一方面是它的插件服务非常强大,Maven本身基本不怎么做事,它基本是调用一些插件来做事。Maven有3套生命周期,clean、compile、site,而每个生命周期中的每个步骤都有一个目标插件来支持。配置每个插件时也都会指明插件的运行时机(即Maven生命周期中的某个步骤)。

    Maven自带强大的依赖管理系统,配置了某个依赖,确定了某个构件的坐标,Maven就能帮我们自动下载构件。

    Maven本身自带一个本地仓库;然后它又为全世界的Java开发者提供了一个免费的“中央仓库”,为了解决本地仓库频繁与中央仓库(存在于外网中)交互,导致效率低的问题,又衍生出了私有仓库,即私服(Nexus)。

时间: 2024-10-27 12:54:01

Maven中的核心概念的相关文章

Mycat中的核心概念

Mycat中的核心概念 1.数据库中间件 Mycat 是一个开源的分布式数据库系统,但是由于真正的数据库需要存储引擎,而 Mycat 并没有 存储引擎,所以并不是完全意义的分布式数据库系统.Mycat 是数据库中间件,就是介于数据库与应用之间,进行数据处理与交互的中间服务.有了数据库中间件,应用只需要集中与业务处理,大量的通用的数据聚合,事务,数据源切换都由中间件来处理,中间件的性能与处理能力将直接决定应用的读写性能,所以一款好的数据库中间件至关重要. 2.逻辑库(schema) 对实际应用来说

maven用途、核心概念、用法、常用参数和命令、扩展

http://trinea.iteye.com/blog/1290898 本文由浅入深,主要介绍maven的用途.核心概念(Pom.Repositories.Artifact.Build Lifecycle.Goal)介绍.用法(Archetype意义及创建各种项目).maven常用参数和命令以及简单故障排除.maven扩展(eclipse.cobertura.findbugs.插件开发).maven配置. 本文较长,可根据个人需要有选择性的查看,比如先看用法再回过头来看核心概念 1.maven

Eureka中的核心概念

服务提供者 Eureka服务治理体系支持跨平台,虽然我们前文使用了Spring Boot来作为服务提供者,但是对于其他技术平台只要支持Eureka通信机制,一样也是可以作为服务提供者,换句话说,服务提供者既可以是Java写的,也可以是python写的,也可以是js写的.这些服务提供者将自己注册到Eureka上,供其它应用发现然后调用,这就是我们的服务提供者,服务提供者主要有如下一些功能: 服务注册 服务提供者在启动的时候会通过发送REST请求将自己注册到Eureka Server上,同时还携带了

react中的核心概念

虚拟DOM 如何实现按需更新? 获取内存中的新旧两棵DOM树进行对比,得到需要被按需更新的DOM树 如何获取新旧DOM树? 分析:浏览器中没有提供直接获取DOM树的API: 方法:我们可以手动模拟新旧DOM树 如何模拟DOM树? 用JS对象 原文地址:https://www.cnblogs.com/embrace-ly/p/10605535.html

Maven核心概念之依赖,聚合与继承

宏观图 一.依赖 我们项目中依赖的jar包可以通过依赖的方式(dependencies元素下添加dependency子元素)引入. <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.10</version> </dependency> 1.依赖范围 通过控制依赖的范围,可以指定该依赖在什么阶段有效. &

Ext JS 6学习文档–第2章–核心概念

核心概念 在下一章我们会构建一个示例项目,而在这之前,你需要学习一些在 Ext JS 中的核心概念,这有助于你更容易理解示例项目.这一章我们将学习以下知识点: 类系统,创建和扩展类 事件 Ext JS 对象的查询 容器 布局 转载请注明出处:http://www.jeeboot.com/archives/1217.html class system(类系统) Ext JS 提供了很多功能,使得它创建和处理类变得简单.以下是在 Ext JS 6 的类系统中的几大组成类: Ext Base Clas

tensorflow核心概念之op

TF中的op代表了对"操作"的抽象,说它抽象是因为,op仅仅说明了操作是做什么用的,但没有说明具体怎么做.举个例子,MatMul是一个操作,它表示了矩阵乘法,但并不包含矩阵乘法的具体实现,因为我们知道,在CPU和GPU上,矩阵乘法的高效率实现是完全不同的.为了把不同设备上的实现细节隐藏起来,为相同的计算提供统一的对外表示,TF提出了op的概念. 为了方便序列化,TF中很多核心概念定义在proto文件中,操作的定义OpDef放在op.proto(/tensorflow/core/fram

ElasticSearch 全文检索— ElasticSearch 核心概念

ElasticSearch核心概念-Cluster 1)代表一个集群,集群中有多个节点,其中有一个为主节点,这个主节点是可以通过选举产生的,主从节点是对于集群内部来说的.es的一个概念就是去中心化,字面上理解就是无中心节点,这是对于集群外部来说的,因为从外部来看es集群,在逻辑上是个整体,你与任何一个节点的通信和与整个es集群通信是等价的. 2)主节点的职责是负责管理集群状态,包括管理分片的状态和副本的状态,以及节点的发现和删除. 3)注意:主节点不负责对数据的增删改查请求进行处理,只负责维护集

Storm 系列(二)—— Storm 核心概念详解

一.Storm核心概念 1.1 Topologies(拓扑) 一个完整的 Storm 流处理程序被称为 Storm topology(拓扑).它是一个是由 Spouts 和 Bolts 通过 Stream 连接起来的有向无环图,Storm 会保持每个提交到集群的 topology 持续地运行,从而处理源源不断的数据流,直到你将主动其杀死 (kill) 为止. 1.2 Streams(流) Stream 是 Storm 中的核心概念.一个 Stream 是一个无界的.以分布式方式并行创建和处理的