Maven的初识
目录
一、项目开发中遇到的问题
1、都是同样的代码,为什么在我的机器上可以编译执行,而在他的机器上就不行?
2、为什么在我的机器上可以正常打包,而配置管理员却打不出来?
3、项目组加入了新的人员,我要给他说明编译环境如何设置,但是让我挠头的是,有些细节我也记不清楚了。
4、我的项目依赖一些jar包,我应该把他们放哪里?放源码库里?
5、这是我开发的第二个项目,还是需要上面的那些jar包,再把它们复制到我当前项目的svn库里吧
6、现在是第三次,再复制一次吧 ----- 这样真的好吗?
7、我写了一个数据库相关的通用类,并且推荐给了其他项目组,现在已经有五个项目组在使用它了,今天我发现了一个 bug,并修正了它,我会把jar包通过邮件发给其他项目组
-----这不是一个好的分发机制,太多的环节可能导致出现bug
8、项目进入测试阶段,每天都要向测试服务器部署一版。每次都手动部署,太麻烦了。
maven就可以解决以上的各种问题
二、Maven 简介
Maven是基于项目对象模型(POM),可以通过一小段描述信息来管理项目的构建,报告和文档的软件项目管理工具。
Maven是跨平台的项目管理工具。主要服务于基于Java平台的项目构建,依赖管理和项目信息管理。
Maven主要有两个功能:
- 项目构建(打包(jar,war),部署)
- 依赖管理(做好配置,自定下载依赖)
三、Maven的安装
1、Maven的安装
第一步:安装jdk,要求1.6或以上版本。
第二步:把maven解压缩,解压目录最好不要有中文。
第三步:配置环境变量MAVEN_HOME
第四步:配置环境变量PATH,将%MAVEN_HOME%\bin加入Path中,在Windows中一定要注意要用分号;与其他值隔开。
第五步:验证是否安装成功,打开cmd窗口,输入mvn–v
2、Maven的配置
Maven有两个settings.xml配置文件,一个是全局配置文件,一个是用户配置文件。
3、全局配置(默认)
%MAVEN_HOME%/conf/settings.xml是maven全局的配置文件。
该配置文件中配置了本地仓库(依赖)的路径,默认就是:~/.m2/repository。其中~表示当前用户路径C:\Users\[UserName]。
localRepository:用户仓库,用于检索依赖包路径
4、用户配置(如果这里设置不了的话,可以在全局配置中设置)
~/.m2/settings.xml是用户的配置文件(默认没有该文件,需要将全局配置文件拷贝过来在进行修改)
注意:一般本地仓库的地址不使用默认配置,通常情况下需要在用户配置中,配置新的仓库地址。
配置步骤如下:
第一步:创建一个本地仓库目录,比如E://repository/maven。
第二步:复制maven的全局配置文件(.settings)到~/.m2目录下,即创建用户配置文件
第三步:修改maven的用户配置文件。
注意:
用户级别的仓库在全局配置中一旦设置,全局配置将不再生效,转用用户所设置的仓库,否则使用全局配置文件中的默认路径仓库(全局:maven/conf/settings.xml用户:用户:~/.m2/settings.xml)
四、创建Maven 工程
Project
| -src
| |-main
| |-java ——存放项目的.java文件
| |-resources ——存放项目资源文件,如spring, hibernate配置文件
| |-webapp———存放jsp,html,web.xml等网页文件WebContent
| |-test测试代码
| |-java ——存放所有测试.java文件,如JUnit测试类
| |-resources ——测试资源文件
| -target ——目标文件输出位置例如.class、.jar、.war文件
| -pom.xml ——maven项目核心配置文件
五、Maven的工程创建
- 第一步:根据maven的目录结构创建HelloMaven工程(target目录会在编译之后自动创建)
- 第二步:创建HelloWorld.java 在src/main/java/com/tf/maven目录下新建文件Hello.java
package com.tf.maven;
public class HelloWorld { public String sayHello(String name){ return "Hello World :" + name + "!"; } } |
- 第三步:创建TestHelloWorld.java
package com.tf.maven;
import org.junit.Test; import static junit.framework.Assert.*;
public class TestHelloWorld{
@Test public void testSayHello(){ HelloWorldhw = new HelloWorld(); String result = hw.sayHello("zhangsan"); assertEquals("hello zhangsan",result); } } |
- 第四步:配置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"> <!--版本:4.0.0 --> <modelVersion>4.0.0</modelVersion> <!--组织名称:暂时使用组织名称+项目名称作为组织名称 --> <!--组织名称:实际名称按照访问路径规范设置,通常以功能作为名称:eg: junit spring --> <groupId>com.qf.maven</groupId> <!--项目名称 --> <artifactId>HelloWorld</artifactId> <!--当前项目版本号:同一个项目开发过程中可以发布多个版本,此处标示0.0.1版 --> <!--当前项目版本号:每个工程发布后可以发布多个版本,依赖时调取不同的版本,使用不同的版本号 --> <version>0.0.1</version> <!--名称:可省略 --> <name>Hello</name>
<!--依赖关系 --> <dependencies> <!--依赖设置 --> <dependency> <!--依赖组织名称 --> <groupId>junit</groupId> <!--依赖项目名称 --> <artifactId>junit</artifactId> <!--依赖版本名称 --> <version>4.9</version> <!--依赖范围:test包下依赖该设置 --> <scope>test</scope> </dependency>
</dependencies> </project>
|
到此maven工程即创建成功。
六、Maven的命令
需要在pom.xml所在目录中执行以下命令。(cmd中执行命令)
1、Mvn compile
- 执行mvn compile命令,完成编译操作
- 执行完毕后,会生成target目录,该目录中存放了编译后的字节码文件。
2、Mvn clean
- 执行完毕后,会将target目录删除。
3、Mvn test
- 执行mvn test命令,完成单元测试操作
- 执行完毕后,会在target目录中生成三个文件夹:surefire、surefire-reports(测试报告)、test-classes(测试的字节码文件)
4、Mvn package
- 执行mvnpackage命令,完成打包操作
- 执行完毕后,会在target目录中生成一个文件,该文件可能是jar、war
5、Mvn install
- 执行mvn install命令,完成将打好的jar包安装到本地仓库的操作
- 执行完毕后,会在本地仓库中出现安装后的jar包,方便其他工程引用
6、mvn clean compile命令
- 组合指令,先执行clean,再执行compile,通常应用于上线前执行,清除测试类
7、mvn clean test命令
- 组合指令,先执行clean,再执行test,通常应用于测试环节
8、mvn clean package命令
- 组合指令,先执行clean,再执行package,将项目打包,通常应用于发布前
- 执行过程:
- 清理————清空环境
- 编译————编译源码
- 测试————测试源码
- 打包————将编译的非测试类打包
9、mvn clean install命令
- cmd中录入mvn clean install 查看仓库,当前项目被发布到仓库中
- 组合指令,先执行clean,再执行install,将项目打包,通常应用于发布前
- 执行过程:
- 清理————清空环境
- 编译————编译源码
- 测试————测试源码
- 打包————将编译的非测试类打包
- 部署————将打好的包发布到资源仓库中
七、使用eclipse创建maven工程配置仓库地址
1、widows –》首选项:maven
2、
八、通过骨架创建maven工程
1、创建工程
- 第一步:选择new→maven→Maven Project
- 第二步:next
- 第三步:next 选择maven的工程骨架,这里我们选择quickstart。
- 第四步:next 输入GroupId、ArtifactId、Version、Package信息点击finish完成。
- 在src/main/java中创建com.tf.maven包,然后创建MavenFirst.java
- 在src/test/java中创建com.tf.maven包,然后创建TestMavenFirst.java
- 执行maven命令进行测试
- 在Eclipse的maven插件中执行maven命令,需要在maven工程或者pom.xml文件上点击右键,选择Run as→maven build..
可以在菜单中看到maven常用的命令已经以菜单的形式出现。
例如:
Maven clean
Maven install
Maven package
Maven test
- Maven build和maven build...并不是maven的命令。
- maven build...只是提供一个命令输入功能,可以在此功能中输入自定义的maven命令。如test、run....
-
maven build的功能就是执行上次自定义命令。
九、不通过骨架创建maven工程
通过选择骨架创建maven工程,每次选择骨架时都需要联网下载,如果网络不通或者较慢的情况下会有很长时间的等待。使用很是不方便,所以创建工程时可以不选择骨架直接创建工程。
创建工程
- 第一步:选择new→maven→Maven Project
- 第二步:next
- 第三步:next
Packaging:指定打包方式,默认为jar。选项有:jar、war、pom。
- 第四步:点击finish,完成maven工程创建。
- 第五步:修改pom文件 在Maven-second工程中依赖使用maven-first工程的代码
十、Maven坐标主要组成
- 什么是坐标?
在平面几何中坐标(x,y)可以标识平面中唯一的一点。在maven中坐标就是为了定位一个唯一确定的jar包。
Maven世界拥有大量构建,我们需要找一个用来唯一标识一个构建的统一规范
拥有了统一规范,就可以把查找工作交给机器
- groupId:定义当前Maven组织名称
- artifactId:定义实际项目名称
- version:定义当前项目的当前版本
- 这三个可以唯一的表示一个项目
1、依赖管理
就是对项目中jar 包的管理。可以在pom文件中定义jar包的GAV坐标,管理依赖。
依赖声明主要包含如下元素:
<dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.9</version> <scope>test</scope> </dependency> </dependencies> |
2、依赖范围 <scope>runtime</scope>
其中依赖范围scope 用来控制依赖和编译,测试,运行的classpath的关系. 主要的是三种依赖关系如下:
1.compile:默认编译依赖范围。对于编译,测试,运行三种classpath都有效
2.test:测试依赖范围。只对于测试classpath有效
3.provided:已提供依赖范围。对于编译,测试的classpath都有效,但对于运行无效。因为由容器已经提供,例如servlet-api
4.runtime:运行时提供。例如:jdbc驱动
3、直接依赖和间接依赖
如果B中使用A,C中使用B,则称B是C的直接依赖,而称A是C的间接依赖。
C->B B->A
C直接依赖B
C间接依赖A
3、依赖范围对传递依赖的影响
左边第一列表示第一直接依赖范围 aàb
上面第一行表示第二直接依赖范围b-->c
中间的交叉单元格表示传递性依赖范围。
总结:
- 当第二依赖的范围是compile的时候,传递性依赖的范围与第一直接依赖的范围一致。
- 当第二直接依赖的范围是test的时候,依赖不会得以传递。
- 当第二依赖的范围是provided的时候,只传递第一直接依赖范围也为provided的依赖,且传递性依赖的范围同样为 provided;
- 当第二直接依赖的范围是runtime的时候,传递性依赖的范围与第一直接依赖的范围一致,但compile例外,此时传递的依赖范围为runtime;
4、依赖冲突
-
如果直接与间接依赖中包含有同一个坐标不同版本的资源依赖,以直接依赖的版本为准(就近原则)
-
a<---bjunit 3.9
- b<--junit 4.1
1、Maven-first工程中依赖log4j-1.2.8版本
那么maven-third中依赖的就是log4j-1.2.8
2、maven-second工程中依赖log4j-1.2.9版本
那么maven-third中依赖的就是log4j-1.2.9,因为它直接依赖的maven-second项目中依赖的就是1.2.9版本
- 如果直接依赖中包含有同一个坐标不同版本的资源依赖,以配置顺序下方的版本为准(就近原则)
Maven-second中依赖log4j-1.2.9和log4j-1.2.14
此时log4j-1.2.14版本生效。
5、可选依赖
- <optional> true/false 是否可选,也可以理解为是否向下传递。
- 在依赖中添加optional选项决定此依赖是否向下传递,
- 如果是true则不传递,如果是false就传递,默认为false。
6、排除依赖
ThirdMavenSecondMavenFirstMaven
<exclusions <exclusion> <groupId>com.tf.maven</groupId> <artifactId>maven-first</artifactId> </exclusion> </exclusions> |
排除依赖包中所包含的依赖关系,不需要添加版本号。
如果在本次依赖中有一些多余的jar包也被传递依赖过来,如果想把这些jar包排除的话可以配置exclusions进行排除。
十一、Maven三大生命周期
clean:清理项目
每套生命周期都由一组阶段(Phase)组成,我们平时在命令行输入的命令总会对应于一个特定的阶段。比如,运行mvn clean ,这个的clean是Clean生命周期的一个阶段。有Clean生命周期,也有clean阶段。Clean生命周期一共包含了三个阶段:
pre-clean 执行一些需要在clean之前完成的工作
clean 移除所有上一次构建生成的文件
post-clean 执行一些需要在clean之后立刻完成的工作
mvn clean 中的clean就是上面的clean,在一个生命周期中,运行某个阶段的时候,它之前的所有阶段都会被运行,也就是说,mvn clean 等同于mvn pre-clean clean ,如果我们运行mvn post-clean ,那么 pre-clean,clean 都会被运行。这是Maven很重要的一个规则,可以大大简化命令行的输入。
default:构建项目
Default生命周期是Maven生命周期中最重要的一个,绝大部分工作都发生在这个生命周期中。这里,只解释一些比较重要和常用的阶段:
validate
generate-sources
process-sources
generate-resources
process-resources 复制并处理资源文件,至目标目录,准备打包。
compile 编译项目的源代码。
process-classes
generate-test-sources
process-test-sources
generate-test-resources
process-test-resources 复制并处理资源文件,至目标测试目录。
test-compile 编译测试源代码。
process-test-classes
test 使用合适的单元测试框架运行测试。这些测试代码不会被打包或部署。
prepare-package
package 接受编译好的代码,打包成可发布的格式,如 JAR 。
pre-integration-test
integration-test
post-integration-test
verify
install 将包安装至本地仓库,以让其它项目依赖。
deploy 将最终的包复制到远程的仓库,以让其它开发人员与项目共享。
运行任何一个阶段的时候,它前面的所有阶段都会被运行,这也就是为什么我们运行mvn install 的时候,代码会被编译,测试,打包。此外,Maven的插件机制是完全依赖Maven的生命周期的,因此理解生命周期至关重要。
site:生成项目站点
pre-site 执行一些需要在生成站点文档之前完成的工作
site 生成项目的站点文档
post-site 执行一些需要在生成站点文档之后完成的工作,并且为部署做准备
site-deploy 将生成的站点文档部署到特定的服务器上
这里经常用到的是site阶段和site-deploy阶段,用以生成和发布Maven站点,这可是Maven相当强大的功能,Manager比较喜欢,文档及统计数据自动生成,很好看。
十二、Maven插件
Maven的核心仅仅定义了抽象的生命周期,具体的任务都是交由插件完成的。每个插件都能实现一个功能,每个功能就是一个插件目标。Maven的生命周期与插件目标相互绑定,以完成某个具体的构建任务。
例如compile就是插件maven-compiler-plugin的一个插件目标
- Maven编译插件 (jre默认的是1.5,添加完插件后,工程右键-->Maven->update project--->Force update....打对勾 )
<build> |
Maven-tomcat插件: Maven build.. --->输入tomacat7:run运行
<!--插件 --> <bulid> <plugins> <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.2</version> <configuration> </plugin> </plugins> </build> |
修改配置文件后,在工程上点击右键选择maven→update project configration
十三、Tomcat插件创建一个maven web工程
- 第一步:不选用骨架
- 第二步:将打包方式选择为war
- 第三步:点击finish,工程创建成功。
- 第四步:在工程中添加web.xml
Web.xml内容如下:
<?xmlversion="1.0"encoding="UTF-8"?> <web-appxmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID"version="2.5"> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> </web-app> |
- 第五步:在webapp下创建index.jsp
出错:因为项目缺少servlet api 和jsp的依赖
<dependency> </dependency> |
十四、修改Maven工程1.5的JRE