maven
eclipse 中创建maven项目需要M2Eclipse插件。
maven介绍
开发中遇到的问题:
- 都是同样的代码,为什么在我的机器上可以编译执行,而在他的机器上就不行?
- 为什么在我的机器上可以正常打包,而配置管理员却打不出来?
- 项目组加入了新的人员,我要给他说明编译环境如何设置,但是让我挠头的是,有些细节我也记不清楚了。
- 我的项目依赖一些jar包,我应该把他们放哪里?放源码库里?
- 这是我开发的第二个项目,还是需要上面的那些jar包,再把它们复制到我当前项目的svn库里吧
- 现在是第三次,再复制一次吧 ----- 这样真的好吗?
- 我写了一个数据库相关的通用类,并且推荐给了其他项目组,现在已经有五个项目组在使用它了,今天我发现了一个bug,并修正了它,我会把jar包通过邮件发给其他项目组
-----这不是一个好的分发机制,太多的环节可能导致出现bug - 项目进入测试阶段,每天都要向测试服务器部署一版。每次都手动部署,太麻烦了。
什么是maven
maven是基于POM(工程对象模型),通过一小段描述来对项目的代码、报告、文件进行管理的工具。
maven是一个跨平台的项目管理工具,它是使用java开发的,它要依赖于jdk1.6以上。
maven主要有两大功能:管理以来、项目构建。依赖就是指的jar包;清理、编译、测试、报告、打包、部署(部署到web服务器)就是项目构建。
项目构建的方式:
- eclipse。使用eclipse进行项目构建,相对来说,步骤比较零散,不好操作。
- Ant
它是一个专门的项目构建工具,它可以通过一些配置来完成项目构建,这些配置要明确的告诉ant,源码包在哪?目标class文件在哪放?资源文件在哪? - maven
它是一个项目管理工具,也是一个项目构建工具,通过使用maven,它可以对项目进行快速简单构建,它不需要告诉maven很多信息,但是需要按照maven规范去进行代码开发。也就是说maven是有约束的。
maven安装配置
- 下载maven,官网下载 http://maven.apache.org/download.cgi
- maven安装
安装jdk,需要1.6以上;
将maven压缩包解压缩;
配置环境变量;
测试maven是否安装成功:mvn -v
Apache Maven 3.3.9 (bb52d8502b132ec0a5a3f4c09453c07478323dc5; 2015-11-11T00:41:47+08:00)
Maven home: /usr/local/apache-maven-3.3.9
Java version: 1.8.0_111, vendor: Oracle Corporation
Java home: /Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home/jre
Default locale: zh_CN, platform encoding: UTF-8
OS name: "mac os x", version: "10.11.6", arch: "x86_64", family: "mac"
- 配置maven
在maven中有两个配置文件:用户配置和全局配置。
3.1 在maven安装目录conf文件夹下 setting.xml。该文件是全局配置文件,配置了本地仓库地址
<!-- localRepository
| The path to the local repository maven will use to store artifacts.
|
| Default: ${user.home}/.m2/repository <localRepository>/path/to/local/repo</localRepository>
-->
默认本地仓库是注释掉的,目录为${user.home}/.m2/repository
3.2 用户配置文件地址在 ~/.m2/settings.xml,该文件默认没有,需要将全局文件拷贝一份放过去。在用户配置文件中
<localRepository>/path/to/local/repo</localRepository>
这个地方重新指定用户本地仓库地址,如果不指定,则默认是 ~/.m2/repository目录,如果用户配置文件不存在,则使用全局配置文件的位置。
创建maven工程
- maven 工程结构
project
| --src(源码包)
| --main(正常源码包)
| --java(.java文件目录)
| --resources(资源目录)
| --test(测试源码包)
| --java
| --resources
| --target(class文件、报告等信息存储的位置)
| --pom.xml(maven工程的描述文件)
- 安装目录结构创建文件夹
编写HelloMaven.java
package com.oranger.maven;
public class HelloMaven {
public String sayHello(String name) {
return "hello" + name;
}
}
- 创建test文件
package com.oranger.maven;
import org.junit.Test;
import static junit.framework.Assert.*;
public class TestHelloMaven {
@Test
public void tesSayHello() {
HelloMaven hm = new HelloMaven();
String result = hm.sayHello("oranger");
assertEquals("hello oranger"result);
}
}
- 编辑pom.xml文件
maven命令
maven命令要在pom.xml文件所在的目录执行
mvn compile
编译
maven会优先从本地仓库加载依赖,如果本地仓库没有会去中央仓库下载
如:
[INFO] Building Hello 0.0.1
[INFO] ------------------------------------------------------------------------
Downloading: https://repo.maven.apache.org/maven2/junit/junit/4.12/junit-4.12.pom
Downloaded: https://repo.maven.apache.org/maven2/junit/junit/4.12/junit-4.12.pom (24 KB at 3.9 KB/sec)
[INFO]
mvn clean
清理编译好的class文件,即target文件夹。
mvn test
跑单元测试的命令,对test文件中的源码进行编译。
mvn package
如果pom.xml中没配置打包的类型,那么默认打出来的是jar包。执行该命令的时候也会执行单元测试。
mvn install
安装命令,会将打好的包安装到本地仓库。这样在本地别的项目中就可以使用对它的依赖。
组合命令
mvn clean compile
先清空,再编译
M2Eclipse
- 安装M2Eclipse(MyEclipse和高版本的Eclipse中自带),下载
- 拷贝到eclipse安装目录中的dropins目录。
- 设置maven安装路径
推荐不使用非骨架创建maven工程,要不然每次下载骨架很麻烦
maven 核心概念
坐标
坐标必须唯一。
Maven坐标主要组成:
groupId:定义当前Maven组织名称
artifactId:定义实际项目名称
version:定义当前项目的当前版本
依赖管理
通过<scope></scope>来指定。
![](./屏幕快照 2017-03-21 下午4.39.03.png)
- compile:默认编译依赖范围。对于编译,测试,运行三种classpath都有效。如log4j
- test:测试依赖范围。只对于测试classpath有效。如junit
- provided:已提供依赖范围。对于编译,测试的classpath都有效,但对运行无效。serlet-api
- runtime:运行时提供。例如:jdbc驱动。
最主要要区分compile和provided。
依赖传递
A、B、C三个工程
B工程依赖A,C工程依赖B。那么B工程是C工程的直接依赖,A工程是C工程的间接依赖。
![](./屏幕快照 2017-03-21 下午5.26.40.png)
![](./屏幕快照 2017-03-21 下午5.26.48.png)
依赖范围对传递依赖的影响
左边第一列表示第一直接依赖范围
上面第一行表示第二直接依赖范围
中间的交叉单元格表示传递性依赖范围。
总结:
• 当第二依赖的范围是compile的时候,传递性依赖的范围与第一直接依赖的范围一致。
• 当第二直接依赖的范围是test的时候,依赖不会得以传递。
• 当第二依赖的范围是provided的时候,只传递第一直接依赖范围也为provided的依赖,且传递性依赖的范围同样为 provided;
• 当第二直接依赖的范围是runtime的时候,传递性依赖的范围与第一直接依赖的范围一致,但compile例外,此时传递的依赖范围为runtime;
依赖冲突
在maven中存在两种冲突方式:一种是跨pom文件的冲突,一种是同一个pom文件的冲突
• 如果直接与间接依赖中包含有同一个坐标不同版本的资源依赖,以直接依赖的版本为准(就近原则)
• 同一个pom文件中的冲突。pom文件从上到下加载,那么下面的jar包会覆盖上面的jar包。这也体现了就近原则。
可选依赖
<optional>true/false</optional>
Optional标签标示该依赖是否可选,默认是false。可以理解为,如果为true,则表示该依赖不会传递下去,如果为false,则会传递下去。
排除依赖
Exclusions标签可以排除依赖
生命周期
生命周期有多个阶段组成。maven有三个生命周期:clean、default、site。
生命周期可以理解为项目构建的步骤集合。生命周期是由多个阶段(Phase)组成。每个阶段都是一个完整的功能,比如mvn clean中的clean就是一个阶段。
clean生命周期
pre-clean 执行一些需要在clean之前完成的工作;
clean 移除所有上一次构建生成的文件 ;
post-clean 执行一些需要在clean之后立刻完成的工作 。
mvn clean命令,等同于 mvn pre-clean clean。只要执行后面的命令,那么前面的命令都会执行,不需要再重新去输入命令。有Clean生命周期,在生命周期又有clean阶段。
default生命周期(重要)
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
将最终的包复制到远程的仓库,以让其它开发人员与项目共享。
在maven中,只要在同一个生命周期,你执行后面的阶段,那么前面的阶段也会被执行,而且不需要额外去输入前面的阶段,这样大大减轻了程序员的工作。
site生命周期
pre-site 执行一些需要在生成站点文档之前完成的工作 ;
site 生成项目的站点文档 ;
post-site 执行一些需要在生成站点文档之后完成的工作,并且为部署做准备 ;
site-deploy 将生成的站点文档部署到特定的服务器上 。
可以自动生成文档及统计数据。
插件
maven的核心仅仅定义了抽象的生命周期,具体任务都是交由插件完成的。每个插件都实现一个功能,每个功能就是插件的一个目标。maven的生命周期与插件目标互相绑定,以完成某个具体的构建任务。
例如compile就是插件maven-compiler-plugin的一个目标插件。
maven编译插件
<!-- 编译插件,指定编译用的jdk版本 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
Tomcat插件
如果使用maven的tomcat插件,那么本地不需要安装tomcat。
创建maven的web工程:
1、 不使用骨架创建,打包方式选择为war
2、在webapp下创建WEB-INF目录,在WEB-INF中创建web.xml文件。
web.xml内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1"
metadata-complete="true">
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
3、在webapp下创建index.jsp文件
4、使用tomcat插件运行web工程
在项目右键,maven build ...,输入tomcat:run,然后点击run。但是默认使用的是tomcat6,要用新的版本需要在pom文件中指定。
<plugin>
<!-- tomcat 插件 -->
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<configuration>
<port>8080</port>
<path>/</path>
</configuration>
</plugin>
如果配置成tomcat7插件,就需要使用命令tomcat7:run。
继承
创建父工程要写成pom形式,现有工程继承父工程需要在pom文件中添加parent节点。
dependencyManagement标签管理的依赖,其实没有真正依赖,它只是管理依赖的版本。
聚合
在真实的项目中,一个项目有表现层、业务层、持久层,对于业务层和持久层,它们可以在多个工程中被使用,所以一般会将业务层、持久层单独创建为java工程,为其他工程依赖。
maven仓库管理
用来统一存储所有Maven共享构建的位置就是仓库。根据Maven坐标定义每个构建在仓库中唯一存储路径大致为:groupId/artifactId/version/artifactId-version.packaging。
本地仓库
默认在~/.m2/repository,如果在用户配置中有配置,则以用户配置的地址为准。
远程仓库
• 中央仓库(不包含有版权的jar包)
http://repo1.maven.org/maven2
Maven私服
安装Nexus
为所有来自中央仓库的构建安装提供本地缓存。
下载网站:http://nexus.sonatype.org/。
安装版本:nexus-2.7.0-06.war
第二步:将nexus的war包拷贝到tomcat的webapps下。
第三步:启动tomcat
第四步:nexus的本地目录
访问Nexus
访问URL: http://localhost:8080/nexus-2.7.0-06/
默认账号:
用户名: admin
密码: admin123