一、背景
maven一般用来管理jar包依赖,构建项目,其他类似优秀的工具有Ant、Gradle
mavne是基于项目对象模型(POM),可以通过一小段描述信息来管理项目的构建、报告和文档的软件项目管理工具
目前很多开源的项目都使用maven来构建,如struts
maven主要解决如下问题
管理jar包的依赖范围
管理jar包的依赖传递
管理jar包的依赖冲突
管理各个模块的聚合和继承
maven项目一般是多个模块的,利用pom.xml文件可以方便的管理各个项目中的关联问题
二、下载
http://maven.apache.org/
下载后,解压配置好相应的settings.xml和环境变量就可以使用了
三、maven配置
3.1 配置环境变量
M2_HOME -->D:\maven\apache-maven-3.3.9
path---> %M2_HOME%\bin;
cmd-测试是否配置成功
mvn -v
3.2生成Maven本地仓库
mvn help:system 命令然后回车,等其执行完后就可以在 C:\Users\Admin\.m2\repository 看到 Maven 下载的一些文件。
注: 本步必须在联网情况下执行,该本地仓库的路径可以在settings.xml文件中配置
3. 3 用户自定义配置
修改maven的配置文件,使其符合我们的使用需要找到maven的安装目录 conf-->settings.xml
用户自定义配置。
Maven有一个全局配置文件为 Maven根目录/conf/settings.xml 文件(比如我的就是 C:\tools\apache-maven-3.2.5\conf\settings.xml),
Maven默认是使用此配置文件,所有用户共享此配置。但是推荐每一个用户配置自己的配置文件,
防止无意思影响系统中其他用户,只需要将全局的配置文件复制到用户目录下的 .m2 文件夹
即可(我的当前用户是 Admin, 所以复制后为 C:\Users\Admin\.m2\settings.xml )。
(如果没有 .m2 文件夹 请先执行上一步,maven会在当前用户的目录下生成 .m2 文件夹)。
3.4 maven项目的目录结构
mian目录下用于写项目代码,test下写测试代码,-resource下存放一些静态资源等
3.5 mavn常用命令
mvn -v :查看mvn版本
mvn complie :编译mvn项目
mvn test :测试
mvn test-compile :编译测试程序
mvn package :打包可以将一个项目快速打成jar包,war包,zip包,pom包等
mvn clean :删除编译产生的target
mvn install :安装jar包到本地仓库
mvn site :生成目标站点
mvn site-depoly:生成目标站点并发布
mvn install:install-file -DgroupId=<groupId> -DartifactId=<artifactId> -Dversion=1.0.0 -Dpackaging=jar -Dfile=<myfile.jar> :安装指定文件到本地仓库
mvn help:effective-pom :查看实际pom信息
mvn dependency:analyze 或 mvn dependency:tree :分析项目的依赖信息
mvn eclipse:eclipse : 生成eclipse项目文件
mvn help:help 或 mvn help:help -Ddetail=true :查看帮助信息
mvn <plug-in>:help,比如:mvn dependency:help 或 mvn ant:help :查看插件的帮助信息
mvn archetype:create -DgroupId=com.mycompany.example -DartifactId=Example :创建一个简单的Java工程
mvn archetype:create -DarchetypeGroupId=org.apache.maven.archetypes -DarchetypeArtifactId=maven-archetype-webapp -DgroupId=com.mycompany.app -DartifactId=my-webapp :创 建一个java的web工程
在cmd中可以使用如下命令快速构建maven目录结构(首先建立一个工程文件夹)
1. mvn archetype:generate 按照提示进行
建议命名风格按照如下方式进行
2. mvn archetype:generate -DgroupId=组织名,公司网址反写+项目名 -DartifactId=项目名+模块名 -Dversion=版本号 -Dpackage=代码所在的包
3.6maven的生命周期
maven的生命周期是顺序进行,在执行下一个声明周期时会先执行之前的声明周期
原文:http://www.cnblogs.com/tenghoo/p/maven_life_cycle.html
推荐文章:http://www.cnblogs.com/luotaoyeah/p/3819001.html
1.Maven的生命周期
Maven的生命周期就是对所有的构建过程进行抽象和统一。包含了项目的清理、初始化、编译、测试、打包、集成测试、验证、部署和站点生成等几乎所有的构建步骤。
Maven的生命周期是抽象的,即生命周期不做任何实际的工作,实际任务由插件完成,类似于设计模式中的模板方法。
2.三套生命周期
Maven有三套相互独立的生命周期,分别是clean、default和site。每个生命周期包含一些阶段(phase),阶段是有顺序的,后面的阶段依赖于前面的阶段。
1、clean生命周期:清理项目,包含三个phase。
1)pre-clean:执行清理前需要完成的工作
2)clean:清理上一次构建生成的文件
3)post-clean:执行清理后需要完成的工作
2、default生命周期:构建项目,重要的phase如下。
1)validate:验证工程是否正确,所有需要的资源是否可用。
2)compile:编译项目的源代码。
3)test:使用合适的单元测试框架来测试已编译的源代码。这些测试不需要已打包和布署。
4)Package:把已编译的代码打包成可发布的格式,比如jar。
5)integration-test:如有需要,将包处理和发布到一个能够进行集成测试的环境。
6)verify:运行所有检查,验证包是否有效且达到质量标准。
7)install:把包安装到maven本地仓库,可以被其他工程作为依赖来使用。
8)Deploy:在集成或者发布环境下执行,将最终版本的包拷贝到远程的repository,使得其他的开发者或者工程可以共享。
3、site生命周期:建立和发布项目站点,phase如下
1)pre-site:生成项目站点之前需要完成的工作
2)site:生成项目站点文档
3)post-site:生成项目站点之后需要完成的工作
4)site-deploy:将项目站点发布到服务器
3.命令行和生命周期
各个生命周期相互独立,一个生命周期的阶段前后依赖。
举例如下:
1、mvn clean
调用clean生命周期的clean阶段,实际执行pre-clean和clean阶段
2、mvn test
调用default生命周期的test阶段,实际执行test以及之前所有阶段
3、mvn clean install
调用clean生命周期的clean阶段和default的install阶段,实际执行pre-clean和clean,install以及之前所有阶段
3.7settings.xml文件配置设置本地仓库的路径(一般 使用自定义的)
不设置该路径,默认会在存放在.m2目录下如---》H:\Users\Mcaox\.m2\repository
配置远程仓库
maven会去本地仓库中找需要的jar,如果不存在,则取远程仓库中找,将jar下载到本地然后供程序使用,上边使用的是公共的镜像仓库
还有其他的一些,配置可以参考http://blog.csdn.net/zuoluoboy/article/details/20007819
默认jdk配置
配置为jdk1.7
如果为私有的仓库可能还需要配置server
四、eclipse中配置maven
4.1配置安装到eclipse
4.2创建maven工程
1选择 maven project 如果需要建立多模块工程选择maven module
2 next
3.选择构建普通工程
4 .输入相应的坐标artifact id将会作为工程名
5. 选择工程右键run as--->maven build... --> goals为命令 (compile,test,package,clean,install)等,如上图compile编译,就会生成target目录,里边存放生成的字节码文件,和测试报告文件等。
五、pom.xml文件解析
每一个maven项目模块都会有一个pom.xml文件,里边可以配置项目的jar包以来,模块以来,添加jetty或tomcat插件等等
我们先看以下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/xsd/maven-4.0.0.xsd">
modelVersion>4.0.0</modelVersion>
<groupId>项目标识(说明该项目属于那个实际项目)</groupId>
<artifactId>项目名+模块名</artifactId>
<!--
第一个0大版本号
第二个0分支版本号
第三个0小版本号
0.0.1-SNAPSHOT 快照班
alpha内测版
beta公测版
release稳定版
GA正式版
-->
<version>0.0.1-SNAPSHOT</version>
<!--指定maven项目的打包方式
默认是 jar
war zip pom
-->
<packaging></packaging>
<!--项目描述名-->
<name></name>
<!--项目地址-->
<url></url>
<!--描述信息-->
<description></description>
<!--开发人员-->
<developers></developers>
<licenses></licenses>
<organization></organization>
<dependencies>
<dependency>
<span style="white-space:pre"> </span><groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<type>jar</type>
<!-- 指定依赖范围,说明该依赖在哪里有用 -->
<scope>test</scope>
<!--设置依赖是否可选默认是false,
如果是false子项目默认是继承的,如果是true子项目必须显示
引入改依赖
-->
<optional></optional>
<!-- 排除依赖传递
A-》B-》C
A依赖于B,B依赖于C
A传递依赖于C
如果A不想依赖于C,只依赖于B则使用该标签排除对C的传递依赖
-->
<exclusions>
<exclusion>
</exclusion>
<exclusions>
</dependency>
</dependencies>
<!--依赖管理-->
<dependencyManagement>
<!--
依赖来不会引入到实际的依赖中
主要定义在父模块中,供子模块继承用
-->
<dependencies>
<dependency>
</dependency>
</dependencies>
</dependencyManagement>
<!--插件列表-->
<build>
<plugins>
<plugin>
<groupId></groupId>
<artifactId></artifactId>
<version></version>
</plugin>
</plugins>
</build>
<!--用于子模块中对父模块中的pom的继承-->
<parent></parent>
<!--用于聚合多个模块的运行,比如之前需要一个一个模块的编译,用这个标签可以实现一起编译-->
<modules>
<module></module>
</modules>
</project>
<groupId></groupId>
<artifactId></artifactId>
<version></version>
这三个一般是必须的
5.1 依赖范围 scope
在maven管网中有详细说明
compile 默认级别范围 ,编译测试运行都有效
provided 测试和编译有效
runtime 测试和运行有效
test 只有测试有效
system 测试和编译有效,可移植性差,有可能会需要依赖本机系统
import 它只使用在dependencyManagement中标识从其他额pom中导入的dependecy配置
import:
test:
5.2依赖传递
建立3个maven工程 mavena、mavenb、mavenc,我们让mavenb依赖mavena, mavenc依赖于mavenb
mavana中的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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.test.mavena</groupId>
<artifactId>mavena</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>mavena</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>
mavenb中的pom.xml文件,引入mavena的依赖
<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.test.mavenb</groupId>
<artifactId>mavenb</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>mavenb</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>
<!-- 引入mavena的依赖
需要将mavena先进行打包,并将其安装到本地仓库中,不然会报mavena-0.0.1-SNAPSHOT.jar找不到
清除上次编译的内容后编译打包
run as -maven build.. - goals clean package
将生成的jar包安装到本地仓库
run as -maven build.. - goals install
-->
<dependency>
<groupId>com.test.mavena</groupId>
<artifactId>mavena</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
mavenc中的pom.xml文件引入对mavenb的依赖
<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.test.mavenb</groupId>
<artifactId>mavenc</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>mavenc</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>
<!--
run as -maven build.. - goals clean package
将生成的jar包安装到本地仓库
run as -maven build.. - goals install
-->
<dependency>
<groupId>com.test.mavenb</groupId>
<artifactId>mavenb</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
工程中jar情况如下图,mavenb中引入了mavena的jar, mavenc引入了mavenb的依赖后同时又mavena的jar和mavenb的jar
5.3依赖冲突,排除依赖
假如我们只想让mavenc依赖于mavenb,将mavenc中的mavena排除,可以使用如下
可以看到mavenc中没有了mavena的依赖
5.4聚合
如上边的做法,分别建立mavena,mavenb,mavenc如果想要将他们打包且安装到本地仓库或编译时,需要分别进行。如果将所有的工程聚合在一起操作就会很方便
这里我们再建立一个maven-aggeraation工程用于聚合mavena,mavenb,mavenc
<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.test.mavend</groupId>
<artifactId>mavend-aggreation</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>mavend-aggreation</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>
<!-- 由于mavend-aggreation工程和其他三个工程是处于一级别
所以需要../回到上级木,不然会找不到其他工程
不过一般我们是建立多模块工程的,有一个父工程,然后又几个子模块
-->
<modules>
<module>../mavena</module>
<module>../mavenb</module>
<module>../mavenc</module>
</modules>
</project>
<packaging>pom</packaging>这个父项目不像之前的项目那样创建一个JAR 或者一个WAR,它仅仅是一个引用其它Maven 项目的POM。pom.xml 中下一部分列出了项目的子模块。在多模块maven项目中这些模块在modules元素中定义,每个modules 元素对应了一个simple-parent/目录下的子目录。Maven知道去这些子目录寻找pom.xml 文件,并且,在构建的simp-parent 的时候,它会将这些子模块包含到要构建的项目中。
当然,仅仅在父项目,配置子项目是不能够真正实现关联的,因为,这毕竟需要子项目的同意,故!子项目中需要配置:(http://blog.csdn.net/eclipser1987/article/details/5739177)
如下
上边我们不是建立的多模块的项目,举一个多模块的例子:父模块中声明聚合的子模块
<modules>
<module>newchnl-common</module>
<module>newchnl-service</module>
<module>newchnl-backend</module>
<module>newchnl-front</module>
</modules>
真正引入的时候需要子模块中同意,所以个子模块中需要声明父模块的坐标
<parent>
<groupId>com.ailk</groupId>
<artifactId>newchnl</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
这样我们编译的时候编译父模块就可以同时编译所有的模块
5.5继承
假如新建一个工程作为付工程maven-parent
<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.test.mavene</groupId>
<artifactId>mavene-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>mavene-parent</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<junit.versioin>3.8.1</junit.versioin>
</properties>
<!-- dependencyManagement 中的依赖不会真的引入该模块,
子类中可以使用parent标签定位父模块中的坐标继承该依赖,然后再子模块中的
dependency标签中引入该(如junit)坐标时,可以不用写version,因为父模块中声明了
-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.versioin}</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
如在mavenc中,继承父模块中的东西
<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.test.mavenb</groupId>
<artifactId>mavenc</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>mavenc</name>
<url>http://maven.apache.org</url>
<!--
直接继承父模块中的依赖
-->
<parent>
<groupId>com.test.mavene</groupId>
<artifactId>mavene-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
六、建立web项目
webdemo项目
新建项目的时候,会报错需要引入servlet的jar包
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
</dependency>
web项目如果目录结构没有,可以手动创建,如果在Project Explorer视图中无法创建,则可以切换到Navigator视图中创建
切换到Project Explorer刷新工程
如果发布代码的时候,测试目录test是不需要的,我们可以将其移除
6.1配置jetty做为web容器
<build>
<finalName>webdemo</finalName>
<plugins>
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.2.10.v20150310</version>
<executions>
<execution>
<!-- 打包完成后使用jetty:run运行 默认端口8080-->
<phase>package</phase>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
上边运行打包命令就可以运行
可以在cmd中使用命令:mvn -Djetty.port=8989 jetty:run 指定端口运行也可以在eclipse中 Run as --> Maven build..-->goals--> -Djetty.port=8989 jetty:run--->run
6.2 配置tomcat插件做web容器
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
Run as --> Maven build..-->goals--> -Dmaven.tomcat.port=8989 tomcat:run--->run
两个关于镜像的的文章:
http://blog.csdn.net/zuoluoboy/article/details/20007819
http://my.oschina.net/heweipo/blog/480244
参考文章:
http://www.cnblogs.com/adolfmc/archive/2012/07/31/2616908.html
http://www.cnblogs.com/tenghoo/p/maven_life_cycle.html
http://www.cnblogs.com/luotaoyeah/p/3819001.html