Maven项目管理工具我想现在很多做过项目的人都会用,虽然新一代构建工具Gradle更加操作配置方便,不过目前感觉还是Maven用的人比较多。
概念:
Maven是基于项目对象模型(POM),可以通过一段描述信息来管理项目的构建、报告和文档的软件项目管理工具。
访问官网:maven.apache.org,点击左边的"download",选择右边相应版本的zip下载解压即可。
解压目录:
bin: 包含mvn的运行脚本
boot:包含一个类加载器框架
conf:配置文件\
lib:第三方和自身的类库
别忘了配置环境变量,这里就不详细说了,之前讲shell编程的时候就说了,配置环境变量的作用是让系统能找到mvn的相关命令。
目录结构:
src
-main
-java
-package
-test
-java
-package
-resources
-pom.xml
下面举个栗子介绍下:
新建项目App,其目录结构:
appTest:
src
-main
-java
com
csdn
appTest
modle
HelloWorld.java
-test
-java
com
csdn
appTest
modle
HelloWorldTest.java (测试类中记得导入junit的jar包,测试方法上加上@Test注解)
-pom.xml
pom.xml如下:
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.csdn.appTest</groupId> //项目组织名
<artifactId>appTest-model</artifactId> //模块名
<version>0.0.1SNAPSHOT</version> //项目版本,"SNAPSHOT"意为"快照"
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
</dependency>
</dependencies>
</project>
打开cmd,若是linux则打开终端,进入项目所在目录,执行"mvn compile",看到提示"BUILD SUCCESSS"即编译成功
之后执行mvn test就会执行测试用例,生成target文件夹,里面有编译生成的字节码文件和测试报告
执行mvn package则会默认将项目打包成jar文件
常用构建命令:
mvn -v 查看版本
mvn test 测试
mvn package 打包
mvn compile 编译
mvn clean 删除target文件
mvn install 安装ja包到本地仓库中
mvn install有什么用呢?
比如先对A项目执行mvn install,就将A项目的jar打包到了本地maven仓库中,而在另一项目B中要使用A项目中的某个类的方法,那么只需在B项目的pom文件中写上A项目的dependecy(依赖)即可,在编译B项目时maven会根据pom中的A项目依赖去本地仓库中找A的jar包并加入项目的classPath中,若找不到会去maven网上的中心仓库中查找。
自动建立目录骨架
之前建立src下的目录文件过程很繁琐,为节省时间,那么我就可以利用archetype插件来自动生成目录。
首先新建一个项目testWork,然后cmd进入该目录,执行"mvn archetype:generate",回车
构建过程中,它会让你选择archetype的版本以及输入项目的groupId,artifactId,version,package,最后输入 "y",目录骨架就创建好了。
还有第二种方式,只是相应的参数事先就声明好了:
执行mvn archetype:generate -DgroupId=com.csdn.maven01 -DartifactId=maven01-demo -Dversion=0.0.1SNAPSHOT -Dpackage=com.csdn.maven01.demo
当然archetype的版本和"y"还是照旧要输入的。
坐标和仓库
坐标指的就是前面已经提到的"groupId","artifactId","version"
仓库分为"本地仓库"和"远程仓库",当本地仓库中没有所需的jar包时,会去远程仓库中查找,并下载到本地仓库中进行使用。
不过maven的中央仓库服务器都在国外,访问速度可能很慢,因此我们可以访问国内的镜像仓库,配置如下:
打开conf文件,打开settings.xml文件,找到mirrors,mirrors中有配置示例,建议配置阿里云镜像仓库,速度很快:
<mirrors>
<mirror>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
</mirrors>
本地仓库位置默认在用户目录下的.m2文件下的repository文件
修改本地仓库路径:还是在settings.xml文件中,找到<localRepository>填写你指定的路径</localRepository>
生命周期和插件
Maven定义了三套生命周期:clean(清理项目)、default(构建项目)、site(生成项目站点),每个生命周期都包含了一些阶段(phase)。三套生命周期相互独立,但各个生命周期中的phase却是有顺序的,且后面的phase依赖于前面的phase。执行某个phase时,其前面的phase会依顺序执行,但不会触发另外两套生命周期中的任何phase。
1 clean生命周期
- pre-clean :执行清理前的工作;
- clean :清理上一次构建生成的所有文件;
- post-clean :执行清理后的工作
2 default生命周期
default生命周期是最核心的,它包含了构建项目时真正需要执行的所有步骤。
- compile :编译项目的源代码;
- test :运行测试代码;
- package :打包成jar或者war或者其他格式的分发包;
- install :将打好的包安装到本地仓库,供其他项目使用;(这四步只是最主要的四步)
3 site生命周期
- pre-site
- site :生成项目的站点文档;
- post-site
- site-deploy :发布生成的站点到服务器上
用户可以根据需要将任何插件目标绑定到任何生命周期的阶段,如:将maven-source-plugin的jar-no-fork目标绑定到default生命周期的package阶段,这样,以后在执行mvn package命令打包项目时,在package阶段之后会执行源代码打包,生成如:ehcache-core-2.5.0-sources.jar形式的源码包。
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.2.1</version>
<executions>
<execution>
<phase>package</phase><!-- 要绑定到的生命周期的阶段 -->
<goals>
<goal>jar-no-fork</goal><!-- 要绑定的插件的目标 -->
</goals>
</execution>
</executions>
</plugin>
</plugins>
……
</build>
再执行mvn package,依次进行compile,test,package以及生成项目源码jar包。
配置插件
Maven插件高度易扩展,可以方便的进行自定义配置。如:配置maven-compiler-plugin插件编译源代码的JDK版本为1.8:
maven官网关于compile插件的一段描述:
"另请注意,目前默认的源设置是1.5,默认的目标设置是1.5,与运行Maven的JDK无关。如果要更改这些默认值,则应按照设置Java编译器的-source和-target中所述设置源和目标"
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
pom.xml常用元素介绍:
<project>:根元素,包含pom的一些约束信息
<modelVersion>:指定当前pom的版本
<groupId>:内容为"反写的公司网址+项目名",定义当前Maven属于哪个项目
<artifactId>:内容为"项目名+模块名",模块的标识,一个项目可能分为好几个模块
<version>:定义当前项目的版本号,比如"0.0.1SNAPSHOT"
第一个0表示大版本号,第二个0表示分支版本号,第三个0表示小版本号
snapshot:快照版,alpha:内部测试版,beta:公测版,Release:稳定版,GA:正式发布
<packaging>:maven项目的打包方式,默认为jar,还有war,zip,pom
<name>:项目描述名
<url>:项目地址
<description>:项目描述
<developers>:开发人员信息
<licenses>:许可证信息
<organization>:组织信息
<dependencies>:依赖列表
<dependency>:依赖项
<groupId>
<artifactId>
<version>
<type>
<scope>:依赖范围,如"test"
<optional>:设置依赖是否可选(true/false),false则默认继承,true则需显示引入该依赖
<exclusions>:排除传递依赖列表
<exclusion>
</exclusions>
</dependency>
</dependencies>
<dependencyManagement>:依赖管理,定义在父模块中,供子模块继承用的
<dependencies>
<dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>
<artifactId>
<version>
</plugin>
</plugins>
</build>
<parent>:用于子模块对父模块pom的继承
<modules>
<module>:指定多个模块一起编译
</modules>
</project>
依赖范围
maven提供了三种classpath:1、编译 2、测试 3、运行
依赖范围是用来控制依赖和三种classpath的关系的,比如junit的test依赖范围,则其只存在"测试"的classpath中
<scope>有
compile:默认的范围,三种classpath都有
provided:编译、测试
runtime:测试、运行
test:测试
system:编译、测试(可移植性差)
import:导入的范围,只使用在dependencyManagement中,表示从其他的pom中导入的dependency配置
依赖传递
比如有三个项目有这样的依赖关系A->B->C,需先将B、C install入库,A在clean compile之后,其Maven dependencies中会B、C,C是传递过来的,可通过将C放入<exclusions><exclusion></exclusion></exclusions>中,自动去除C的依赖
依赖冲突
依赖冲突是说当A有多条依赖路径,比如:A->B->C->X1,A->D->X2,X1和X2是指X的不同版本,那么A究竟会依赖哪个版本的X?有两个原则:
短路优先原则:
A->D->X2的路径更短,则A会依赖X2版本
谁先声明依赖谁:
若两条路径长度是一样的,A->C->X1,A->B->X2,那么在写pom文件时,若C的依赖写在B的前面,则依赖X1版本
聚合和继承
聚合
一个一个地将模块install入库较麻烦,这时可以用聚合的方式,新建一个maven项目A,pom中的packaging元素改成pom,在<modules>中新增你要install的若干<module>,现在只要install A就能同时生成<module>指定的jar包并入库
继承
当A,B,C都同时依赖某个jar时,比如junit,可以写个父模块,pom中的packaging元素改成pom,写上junit的依赖,并将dependencies元素放入dependencyment元素中,而在A,B,C中新增<parent>元素并写入父模块的坐标,原本关于junit的dependency中可删除scope,version属性,虽然看上去代码没有减少, 反而增多,不过这是为了提高代码重用性以及便于后期维护与扩展.