maven的认识跟简单使用
maven的简单使用
1、maven的使用背景
maven是一个成熟的项目管理工具,它的核心理念是POM(Project Object Model)项目对象模型,把一整个项目当做对象,类似Java的OOP(面向对象)。是可以通过描述信息来完成项目
的构建。
maven有一个很重要的概念叫做“仓库”(repository),在传统保守的开发模式中,以下情形很常见:
我们会在工作中同时创建很多项目,每个项目可能都会引用一些公用的jar包,一种作法是每个项目里,都复制一份这些依赖的jar包(或dll文件),这样显然不好,相同的文件在硬盘上保存了多份,太占用空间,
而且这些依赖的jar包(或dll文件)的版本也不太好管理(比如某个公用的jar包,从1.0升级到2.0,如果所有引用这个jar包的项目都需要更新,必须一个个项目的修改)。
maven的仓库则很好的解决了这些问题,它在每台机器上创建一个本机仓库,把本机上所有maven项目依赖的jar包统一管理起来,而且这些jar包用“坐标”来唯一标识(理解成“唯一识别某个jar包文件名、版本号”的标识即可),这样所有maven项目就不需要再象以前那样把jar包复制到lib目录中,整个maven项目看起来十分清爽。
2、安装maven和配置环境变量
先从官网http://maven.apache.org/download.cgi 下载最新版本,下载完毕后解压压缩文件到某个路径,如:E:\apache-maven-3.3.9
然后配置环境变量,做法和配置jdk的环境变量类似:新建一个MAVEN_HOME:E:\apache-maven-3.3.9的变量,然后在Path中加入;%MAVEN_HOME%/bin即可。
在dos窗口运行命令mvn -v 如果出现maven的安装版本信息,说明maven安装成功~ 注意:mvn是maven的核心指令。
在使用
3、仓库和settings.xml配置文件
settings.xml配置文件是用于确定maven在运行时的各种配置的。这包含了本地仓库位置,远程仓库服务器以及认证信息等。
settings.xml存在于两个地方:
一是用户安装目录:%MAVEN_HOME%/conf/settings.xml --用户配置,
二是用户的目录如:C:/Users/用户名/.m2/settings.xml --全局配置
用户配置优先全局配置,都存在时,内容将被合并。
下面以一个典型的settings.xml配置文件来说下:
<settings> <!-- 本地仓库的配置,默认是C:/Users/用户名/.m2/repository --> <localRepository>E:\mvn-repository</localRepository> <!-- 是否需要和用户交互获得输入 --> <interactiveMode>true</interactiveMode> <!-- 是否需要在离线模式下运行 --> <offline>false</offline> <!--远程仓库的镜像列表 --> <mirrors> <mirror> <!--镜像的ID --> <id>xx-repository</id> <!-- 镜像名 --> <name>test Repository Manager</name> <!--该镜像的URL。构建系统会优先考虑使用该URL,而非使用默认的服务器URL。 --> <url>http://xx.xx.xx.xx:10000/nexus/content/groups/test</url> <!-- 被镜像的服务器ID,用*表示所有 --> <mirrorOf>*</mirrorOf> </mirror> </mirrors> <!-- 服务端的一些设置 --> <servers> <server> <!--server的id --> <id>xxx</id> <!--鉴权用户名。鉴权用户名和鉴权密码表示服务器认证所需要的登录名和密码。 --> <username>xxx</username> <!--鉴权密码 。鉴权用户名和鉴权密码表示服务器认证所需要的登录名和密码。 --> <password>xxxx</password> </server> <server> <id>xxx</id> <username>xxx</username> <password>xxxx</password> </server> </servers> <!--根据环境参数来调整构建配置的列表。--> <profiles> <!--根据环境参数来调整的构件的配置 --> <profile> <!-- 配置的唯一标识 --> <id>xxx</id> <!--自动触发profile的条件逻辑。Activation是profile的开启钥匙。--> <activation> <!-- profile默认是否激活的标识 --> <activeByDefault>true</activeByDefault> <!-- jdk的版本 --> <jdk>1.7</jdk> </activation> <!--远程仓库列表,它是Maven用来填充构建系统本地仓库所使用的一组远程项目。 --> <repositories> <repository> <!-- 远程仓库的唯一标识 --> <id>center</id> <!--远程仓库名--> <name>center</name> <!--如何处理远程仓库里发布版本的下载--> <releases> <!--true或者false表示该仓库是否为下载某种类型构件(发布版,快照版)开启。 --> <enabled>true</enabled> <!-- 指定本地仓库更新的频率,即与远程仓库同步的频率。 --> <updatePolicy>always</updatePolicy><!-- always(一直),daily(默认,每日),interval:X(这里X是以分钟为单位的时间间隔),或者never(从不)。 --> <!--当Maven验证构件校验文件失败时该怎么做:--> <checksumPolicy>warn</checksumPolicy><!--ignore(忽略),fail(失败),或者warn(警告)。 --> </releases> <!--如何处理远程仓库里快照版本的下载。有了releases和snapshots这两组配置,POM就可以在每个单独的仓库中,为每种类型的构件采取不同的策略。--> <snapshots> <enabled>true</enabled> <updatePolicy>always</updatePolicy> <checksumPolicy>fail</checksumPolicy> </snapshots> <!--远程仓库URL--> <url>http://xx.xx.xx.xx:10000/nexus/content/groups/test</url> <!--用于定位和排序构件的仓库布局类型-可以是default(默认)或者legacy(遗留)。--> <layout>default</layout> </repository> </repositories> <!--发现插件的远程仓库列表。仓库是两种主要构件的家。第一种构件被用作其它构件的依赖。这是中央仓库中存储的大部分构件类型。另外一种构件类型是插件。--> <pluginRepositories> <!--连接到远程插件仓库的信息,与repository类似--> <pluginRepository> <id>plugins</id> <name>Plugins</name> <releases> <enabled>true</enabled> <updatePolicy>always</updatePolicy> <checksumPolicy>warn</checksumPolicy> </releases> <snapshots> <enabled>true</enabled> <updatePolicy>always</updatePolicy> <checksumPolicy>fail</checksumPolicy> </snapshots> <url>http://xx.xx.xx.xx:10000/nexus/content/groups/test</url> <layout>default</layout> </pluginRepository> </pluginRepositories> </profile> </profiles> <!-- 手动激活profiles的列表 --> <!--任何在activeProfile中定义的profile id,不论环境设置如何,其对应的 profile都会被激活。--> <!--如果没有匹配的profile,则什么都不会发生。例如,env-test是一个activeProfile,则在pom.xml(或者profile.xml)中对应id的profile会被激活。--> <activeProfiles> <activeProfile>test</activeProfile> </activeProfiles> </settings>
关于该配置文件的说明注释已经给出。
注:在第一次从远程导入项目或创建项目的时候,会从指定镜像下载jar包信息到本地仓库,今后本地项目依赖的jar包就位于本地仓库了。
4、创建maven项目
1)首先切换到工作目录如:F:/gitwork
2)在该目录下运行命令mvn archetype:generate就能创建一个maven项目,但是建议同时带上多个参数:
-DgroupId=com.company.appname 组id
-DartifactId=appname 项目名称,maven会根据这个名称在当前目录下新建一个名为该名称的目录用于建立项目
-DinteractiveMode=false 是否已交互模式进行,如果是false的话就会采用默认设置建立项目
如:mvn archetype:generate -DgroupId=com.test -DartifactId=maven-hello -DinteractiveMode=false (默认创建一般java项目)
和:mvn archetype:generate -DarchetypeGroupId=org.apache.maven.archetypes -DarchetypeArtifactId=maven-archetype-webapp -DgroupId=com.company.appname -DartifactId=appname(创建web项目)
当然在实际开发中一般是远程导入或者利用IDE工具创建~
3)我们把创建好的maven项目import到IDE工具比如说Eclipse中:
一般项目:
主要关注一般项目的结构:
src/main/java——存放java代码的地方;
src/test/java——存放测试代码的地方
target——存放编译文件的地方
pom.xml——描述该maven项目信息的配置文件
web项目:
主要结构跟一般项目类似(只是这里默认创建的没有存放Java代码的地方,可以自己建包),主要是多了几个地方:
src/main/resources ——存放资源文件的地方;
webapp ——存放xml等配置文件的地方,如Spring的配置文件。
5.了解pom.xml配置文件
pom中的主要关系分为:继承、依赖和聚合,这三种关系并不是相互独立的,它们往往是结合在一起使用的。
在创建一个maven项目以后,会在项目的根目录下生成一个pom.xml的配置文件。
pom.xml文件是Maven进行工作的主要配置文件。Maven在建立项目的时候是基于Maven项目下的pom.xml进行的,我们项目依赖的信息和一些基本信息都是在这个文件里面定义的。
对于一个最简单的pom.xml的定义必须包含modelVersion、groupId、artifactId和version这四个元素,当然这其中的元素也是可以从它的父项目中继承的。
在Maven中,使用groupId、artifactId和version组成groupdId:artifactId:version的形式来唯一确定一个项目。
1)pom的依赖
最为常见,就是前面说到的仓库相关的概念,我们依赖一个jar包或工程只需在dependencies节点下添加一个dependency子节点即可~
<dependency><!-- 这是依赖另外一个工程的格式,如果是依赖jar包的话要另外写--> <groupId>cn.itcast.maven</groupId> <artifactId>HelloFriend</artifactId> <version>0.0.1-SNAPSHOT</version> <scope>compile</scope> </dependency>
依赖jar包:
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency>
2)pom的继承
前面说了pom有点类似oop,我们可以把整个项目理解成一个对象。巧的是,pom也有继承。
继承为了消除重复,我们把很多相同的配置提取出来(比如在maven相互依赖的项目中,不同的项目中却有相同的jar包配置,那样不是显得非常多而且繁琐,每次都需要去配置它,很麻烦)
所以,maven提供了一个父类maven项目(新建父类工程Parent,目的消除子工程的配置文件中重复的内容)来装所有公共使用的jar,只要继承都可以使用。
首先在parent项目的pom.xml配置依赖的公共jar包,然后在各子项目中引入父项目,一般放在<dependencies>节点上面,此时各个子项目就无需在pom.xml中加入公共jar包的依赖,只需添加各自
需要的jar包依赖即可。
<parent> <groupId>cn.itcast.maven</groupId> <artifactId>Parent</artifactId> <version>0.0.1-SNAPSHOT</version> <relativePath>../Parent/pom.xml</relativePath> </parent>
但此时父项目是一个聚合工程,没有实际代码。它的pom.xml的packaging应为pom。
3)pom的聚合
在开发的过程中,我们常常会有分模块开发的做法,比如一个工程,有web模块(直接跟UI交互的模块),有facade模块(通过webservice提供给其他项目使用的接口模块),
service模块(实现其他项目接口模块的功能模块)等等,这些如果不分模块就会显得很杂乱,而分了模块以后层次就会清晰得多。maven对各模块(实际上也是一个工程)的管理提供了支持,
就是聚合。
在父工程(被聚合对象)中,pom.xml的modules部分定义成如下的样式:
<groupId>com.web</groupId> <artifactId>maven-web</artifactId> <packaging>pom</packaging> ..... <modules> <module>maven-web-facade</module> <!--各module属性的值是各模块的artifactId--> <module>maven-web-service</module> ..... </modules>
而各子模块,如facade模块的pom.xml:
<parent> <groupId>com.myhost.myapp</groupId> <artifactId>myapp</artifactId> <version>1.0</version> </parent> <groupId>com.myhost.myapp</groupId> <artifactId>myapp-facade</artifactId> <version>1.0</version> <name>myapp-facade</name>
同理,service模块的pom.xml:
<parent> <groupId>com.web</groupId> <artifactId>maven-web</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <groupId>com.web</groupId> <artifactId>maven-web-service</artifactId> <version>0.0.1-SNAPSHOT</version> <name>maven-web-service</name>
为了直观感受,建议在eclipse里建一个working set,把聚合与被聚合的项目放在同一个working set里。然后eclispe里的Pacakge Exploer的Top Level Elements倒三角里选“Working Set”,
显示效果如下: