培训会网站建设,网页设计与网站建设全攻略pdf,制作网站建设策划方案,oa厂家排名前两天在一个技术群#xff0c;有人还在问maven中groupId、artifactId、version这些关键字的含义是什么#xff0c;于是#xff0c;我觉得还是很有必要来聊聊Maven中的这些核心概念。
成功不是将来才有的#xff0c;而是从决定去做的那一刻起#xff0c;持续累积而成。
…前两天在一个技术群有人还在问maven中groupId、artifactId、version这些关键字的含义是什么于是我觉得还是很有必要来聊聊Maven中的这些核心概念。
成功不是将来才有的而是从决定去做的那一刻起持续累积而成。
今天我们来学习Maven中的核心概念。了解了这些核心概念后我们后面就可以更深层次的学习和使用Maven。 坐标
坐标的概念
来自百度百科
能够确定一个点在空间的位置的一个或一组数叫做这个点的坐标。通常由这个点到垂直相交的若干条固定的直线的距离来表示 。这些直线叫做坐标轴。坐标轴的数目在平面上为2x,y在空间里为3(x,y,z)。 其实就是可以标识平面中或空间里唯一的一个点。
Maven中的坐标
Maven其中一个核心的作用就是管理项目的依赖引入我们所需的各种jar包等。为了能自动化的解析任何一个Java构件Maven必须将这些Jar包或者其他资源进行唯一标识这是管理项目的依赖的基础也就是我们要说的坐标。包括我们自己开发的项目也是要通过坐标进行唯一标识的这样才能才其它项目中进行依赖引用。
案例
依赖时候:比如下面我们依赖junit的jar包。
!-- pom.xml中 --
dependencygroupIdjunit/groupIdartifactIdjunit/artifactIdversion3.8.1/versionscopetest/scope
/dependency项目中定义我们的项目将打成jar或者war包。
?xml version1.0 encodingUTF-8?
project xmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersiongroupIdcom.tian/groupIdartifactIdmaven-demo/artifactIdversion1.0-SNAPSHOT/version!-- 默认是jar --packagingjar/packaging
/project最后打出来的jar或war的形式的形式
artifactid-version.jar
artifactid-version.war
packaging 标签默认是jar所以通常我们在没有指定打成jar包还是war的时候最终打成的就是jar包。
Maven坐标的组成
「groupId」组织标识包名。定义当前Maven项目隶属的实际项目。首先Maven项目和实际项目不一定是一对一的关系。比如SpringFrameWork这一实际项目其对应的Maven项目会有很多如spring-core,spring-context等。这是由于Maven中模块的概念因此一个实际项目往往会被划分成很多模块。其次groupId不应该对应项目隶属的组织或公司。原因很简单一个组织下会有很多实际项目如果groupId只定义到组织级别而后面我们会看到artifactId只能定义Maven项目模块那么实际项目这个层次将难以定义。最后groupId的表示方式与Java包名的表达方式类似通常与域名反向一一对应。上例中groupId为junit是不是感觉很特殊这样也是可以的因为全世界就这么个junit它也没有很多分支。
「artifactId」项目名称。该元素定义当前实际项目中的一个Maven项目模块推荐的做法是使用实际项目名称作为artifactId的前缀。比如上例中的junitjunit就是实际的项目名称方便而且直观。在默认情况下maven生成的构件会以artifactId作为文件头如junit-3.8.1.jar使用实际项目名称作为前缀就能方便的从本地仓库找到某个项目的构件。
「version」项目的当前版本或者我们要依赖jar的版本。该元素定义了使用构件的版本如上例中junit的版本是3.8.1你也可以改为4.0表示使用4.0版本的junit。
「packaging」项目的打包方式最为常见的jar和war两种默认是jar。定义Maven项目打包的方式使用构件的什么包。首先打包方式通常与所生成构件的文件扩展名对应如上例中没有packaging则默认为jar包最终的文件名为junit-3.8.1.jar。也可以打包成war等。
「classifier」 该元素用来帮助定义构建输出的一些附件。附属构件与主构件对应如上例中的主构件为junit-3.8.1.jar,该项目可能还会通过一些插件生成如junit-3.8.1-javadoc.jar,junit-3.8.1-sources.jar, 这样附属构件也就拥有了自己唯一的坐标。
上述5个元素中groupId、artifactId、version是必须定义的packaging是可选的默认为jar而classfier是不能直接定义的需要结合插件使用。
Maven为什么使用坐标呢
Maven世界里拥有大量构建我们需要找一个用来唯一标识一个构建的统一规范。拥有了统一规范就可以把查找工作交给机器。
maven依赖管理
依赖
依赖通常表现为我需要你的东西就像情侣之间相互依赖夫妻之间相互依赖人依赖于水人依赖于粮食等。
在Maven中则表现为项目中用到b.jar包的每个类此时的项目就依赖b.jar。
复杂点关系就是多层依赖a.jar包依赖b.jar包还有可能b.jar包依赖c.jar。这种现象也可以称之为依赖传递性。 我们的项目间接性的依赖了b.jar。
依赖配置
Maven中依赖配置案例如下
!--添加依赖配置--
dependencies!--项目要使用到junit的jar包所以在这里添加junit的jar包的依赖--dependencygroupIdjunit/groupIdartifactIdjunit/artifactIdversion4.9/versionscopetest/scope/dependency!--项目要使用到Hello的jar包所以在这里添加Hello的jar包的依赖--dependencygroupIdcom.tian.maven/groupIdartifactIduser-service/artifactIdversion0.0.1-SNAPSHOT/versionscopecompile/scope!-- 依赖范围--/dependency
/dependencies依赖范围
所谓的依赖范围就是指我们在什么需要依赖的jar。有的是在编译的时候就需要有的是测试的时候需要等。
依赖范围scope有以下6种
「compile」 默认编译依赖范围。对于编译测试运行三种classpath都有效。即在编译、测试和运行的时候都要使用该依赖jar包
「test」测试依赖范围。只对于测试classpath有效。而在编译和运行项目时无法使用此类依赖典型的是JUnit它只用于编译测试代码和运行测试代码的时候才需要
「provided」已提供依赖范围。对于编译测试的classpath都有效但对于运行无效。因为由容器已经提供例如servlet-api.jar这个在编译和测试的时候需要用到但是在运行的时候web容器已经提供了就不需要maven帮忙引入了。
「runtime」运行时依赖范围使用此依赖范围的maven依赖对于编译测试、运行测试和运行项目的classpath有效但在编译主代码时无效比如jdbc驱动实现运行的时候才需要具体的jdbc驱动实现。
「system」系统依赖范围使用system范围的依赖时必须通过systemPath元素显示地指定依赖文件的路径不依赖Maven仓库解析所以可能会造成建构的不可移植即就是在你的电脑上可能没问题但是到别人电脑上那就说不清楚了有点类似provided 注意这个system谨慎使用。
systemPath${java.home}/lib/rt.jar/systemPath「import」仅pom在本节中的类型依赖项上支持此作用域。它指示依赖关系将被指定的pom部分中的有效依赖关系列表替换。由于已替换它们因此范围为的依赖项import实际上不会参与限制依赖项的可传递性在springboot和springcloud中用到的比较多。
以上六种范围中常用的有compile、test、runtime、provided 。
依赖范围不仅可以控制与三种classpath的关系还对传递性依赖产生影响依赖关系图如下 「注意」预期这应该是运行时范围因此必须明确列出所有编译依赖项。但是如果您依赖的库从另一个库扩展了一个类则两者都必须在编译时可用。因此即使编译时间相关性是可传递的它们仍保留为编译范围。
Maven仓库管理
Maven仓库
用来统一存储所有Maven共享构建的位置说白了就是用来存放jar包的我们本地每次编译的时候没有对应jar包是编译通不过的我们一个项目中是需要很多jar的依赖的这时候就知道仓库的重要性了。
Maven仓库布局
根据Maven坐标定义每个构建在仓库中唯一存储路径大致为
groupId/artifactId/version/artifactId-version.packaging
本地仓库
在上一篇文章中每个用户只有一个本地仓库默认是在~/.m2/repository/~代表的是用户目录 。为了便于管理一般都会自己搞一目录专门用来存储本地仓库内容。这样我们开发的时候依赖那个jar就直接去我们的本地仓库repository中去查找如果没有我们会从中央仓库中拉取。
中央仓库
基本上保存了对外开发的所有jar包Maven默认的远程仓库外国网站URL地址http://search.maven.org/ 。还有比如阿里的仓库我们在开发的时候由于网络原因很多人都喜欢使用阿里的这个仓库http://maven.aliyun.com 。
这时候我们本地仓库和中央仓库的关系 私服
大部分公司都会搭建私服私服就是一种特殊的远程仓库它是架设在局域网内的仓库 。比如公司搭建局域网公司也搞个仓库然后开发人员就直接使用公司搭建的私服就行了这样大大减少了网络开销以及开发成本有时候外网访问很慢会浪费大家开发时间的。
这样开发人员每次需要每个jar包就直接从公司的私服里拉取不需要使用外网去中央仓库里拉取了。总之节约时间和节约网络开始。并且有些企业还是不给外网的这时候你就知道这个私服的重要性了。
增加了私服后本地仓库私服中央仓库的关系图 面试中也频繁被问本地仓库、私服以及中央仓库是什么关系
Maven生命周期
Maven的 生命周期从我们的项目构建一直到项目发布的这个过程。 每个阶段的说明 为了完成 default 生命周期这些阶段(包括其他未在上面罗列的生命周期阶段)将被按顺序地执行。
Maven 有以下三个标准的生命周期
Clean Lifecycle 在进行真正的构建之前进行一些清理工作。Default Lifecycle 构建的核心部分编译测试打包部署等等。Site Lifecycle 生成项目报告站点发布站点。
这三个标准它们是相互独立的你可以仅仅调用clean来清理工作目录仅仅调用site来生成站点。当然你也可以直接运行 mvn clean install site运行所有这三套生命周期。
运行任何一个阶段的时候它前面的所有阶段都会被运行这也就是为什么我们运行mvn install 的时候代码会被编译测试打包。此外Maven的插件机制是完全依赖Maven的生命周期的因此理解生命周期至关重要。
Maven插件
Maven是不做具体事情的只是规定了生命周期的各个阶段和步骤由集成到 Maven 中的插件完成。
Maven的核心仅仅定义了抽象的生命周期具体的任务都是交由插件完成的。每个插件都能实现多个功能每个功能就是一个插件目标。Maven的生命周期与插件目标相互绑定以完成某个具体的构建任务 例如compile就是插件maven-compiler-plugin的一个插件目标。
关于插件这里就说个大概后续会出一篇文章专门来说Maven插件。
排除不需要依赖
dependencygroupIdcom.tian.maven/groupIdartifactIdmy-maven/artifactIdversion1.0.0/versionexclusionsexclusiongroupIdcom.tian.maven/groupIdartifactIdyour-maven/artifactId/exclusion/exclusions
/dependency上面使用使用exclusions元素排除了my-maven-your-maven依赖的传递也就是my-maven-your-maven不会被传递到当前项目中。
exclusions中可以有多个exclusion元素可以排除一个或者多个依赖的传递声明exclusion时只需要写上groupId、artifactId就可以了version可以省略。
总结
本文讲述Maven坐标Maven依赖管理、Maven仓库管理、Maven生命周期以及简单介绍了Maven插件。有了这些概念作为铺垫我们就可以更深层次去体会为什么我们在工作室这么用的。