文章目录
1. Maven简介
百度百科说明:
Maven项目对象模型(POM),可以通过一小段描述信息来管理项目的构建,报告和文档的项目管理工具软件。
Maven 除了以程序构建能力为特色之外,还提供高级项目管理工具。由于 Maven 的缺省构建规则有较高的可重用性,所以常常用两三行 Maven 构建脚本就可以构建简单的项目。由于 Maven 的面向项目的方法,许多 Apache Jakarta 项目发文时使用 Maven,而且公司项目采用 Maven 的比例在持续增长。
Maven这个单词来自于意第绪语(犹太语),意为知识的积累,最初在Jakata Turbine项目中用来简化构建过程。当时有一些项目(有各自Ant build文件),仅有细微的差别,而JAR文件都由CVS来维护。于是希望有一种标准化的方式构建项目,一个清晰的方式定义项目的组成,一个容易的方式发布项目的信息,以及一种简单的方式在多个项目中共享JARs。
总而言之,Maven是一个基于java平台的自动化构建工具。
1.1 构建工具演化史
构建工具历史:
make->ant->maven->gradle
2. Maven的作用
简单来说,Maven是用来通过POM文件实现对项目依赖的管理和项目的自动构建:
- 管理Jar
- 自动增加第三放jar
- 管理jar包之间的依赖关系,自动关联下载所有依赖的jar,不会冲突
- 将项目拆分成若干个模块
- 第一层…模块
第二层…模块
第三层…模块
…- 将多个项目(模块)组合到一起
3. Maven生命周期
Maven的生命周期包括很多,但是这里只做简单介绍。具体请参考菜鸟教程-Maven构建生命周期
一个典型的Default (Build) 生命周期
如下图所示:
说明:
为了完成 default 生命周期,这些阶段(包括其他未在上面罗列的生命周期阶段)将被按顺序地执行。
以下是各个阶段的具体阐述:
生命周期阶段 |
|
---|---|
validate | 验证项目是否正确且所有必须信息是可用的 |
compile | 源代码编译在此阶段完成,java->classname |
test | 使用适当的单元测试框架(例如JUnit)运行测试 单元测试 开发人员 测试人员 |
package | 将项目中包含的 多个文件 压缩成 一个文件 用于安装或者部署 (java-jar包 web-war包) |
verify | 对集成测试的结果进行检查,以保证质量达标 |
install | 将打成的包 放到 本地仓库 供其他项目使用 |
deploy | 将打成的包 放到 服务器上 共享给其他开发人员和工程 |
3.1 Maven的三个标准生命周期
Maven 有以下三个标准的生命周期:
clean lifecycle
:项目清理的处理default(或 build) lifecycle
:项目部署的处理site lifecycle
:项目站点文档创建的处理
3.1.1 生命周期和构建的关系
假设执行顺序a b c d e :
执行后面的命令会执行前面的命令
例如执行d时候 会把 abc都执行一次
3.2 Clean LifeCycle
当我们执行 mvn post-clean 命令时,Maven 调用 clean 生命周期,它包含以下阶段:
生命周期阶段 | 描述 |
---|---|
pre-clean | 执行一些需要在clean之前完成的工作 |
clean | 移除所有上一次构建生成的文件,为重新编译做准备 |
post-clean | 执行一些需要在clean之后立刻完成的工作 |
针对3.1.1中所说的生命周期和构建的关系,可以知道:
如果运行mvn post-clean,那么实际上执行的是
pre-clean, clean, post-clean
3.3 Default (Build) LifeCycle
这是 Maven 的主要生命周期,被用于构建应用,包括下面的 23 个阶段:
|
|
---|---|
validate (校验) | 校验项目是否正确并且所有必要的信息可以完成项目的构建过程。 |
initialize (初始化) | 初始化构建状态,比如设置属性值。 |
generate-sources(生成源代码) | 生成包含在编译阶段中的任何源代码。 |
process-sources (处理源代码) | 处理源代码,比如说,过滤任意值。 |
generate-resources (生成资源文件) | 生成将会包含在项目包中的资源文件。 |
process-resources (处理资源文件) | 复制和处理资源到目标目录,为打包阶段最好准备。 |
compile (编译) | 编译项目的源代码。 |
process-classes (处理类文件) | 处理编译生成的文件,比如说对Java |
generate-test-sources (生成测试源代码) | 生成包含在编译阶段中的任何测试源代码。 |
process-test-sources (处理测试源代码) | 处理测试源代码,比如说,过滤任意值。 |
generate-test-resources (生成测试资源文件) | 为测试创建资源文件。 |
process-test-resources (处理测试资源文件) | 复制和处理测试资源到目标目录。 |
test-compile (编译测试源码) | 编译测试源代码到测试目标目录. |
process-test-classes (处理测试类文件) | 处理测试源码编译生成的文件。 |
test (测试) | 使用合适的单元测试框架运行测试(Juint 是其中之一)。 |
prepare-package (准备打包) | 在实际打包之前,执行任何的必要的操作为打包做准备。 |
package (打包) | 将编译后的代码打包成可分发格式的文件,比如JAR 、WAR 或者EAR 文件。 |
pre-integration-test (集成测试前) | 在执行集成测试前进行必要的动作。比如说,搭建需要的环境。 |
integration-test (集成测试) | 处理和部署项目到可以运行集成测试环境中。 |
post-integration-test (集成测试后) | 在执行集成测试完成后进行必要的动作。比如说,清理集成测试环境。 |
verify (验证) | 运行任意的检查来验证项目包有效且达到质量标准。 |
install (安装) | 安装项目包到本地仓库,这样项目包可以用作其他本地项目的依赖。 |
deploy (部署) | 将最终的项目包复制到远程仓库中与其他开发者和项目共享。 |
说明:
- 当一个阶段通过 Maven 命令调用时,例如 mvn compile,只有该阶段之前以及包括该阶段在内的所有阶段会被执行。例如mvn install,这个命令在执行 install 阶段前,按顺序执行了 default 生命周期的阶段 (validate,compile,package,等等)
- 不同的 maven 目标将根据打包的类型(JAR / WAR / EAR),被绑定到不同的 Maven 生命周期阶段。
- 在构建环境中,使用
mvn clean deploy
调用来纯净地构建和部署项目到共享仓库中。这行命令也可以用于多模块的情况下,即包含多个子项目的项目,Maven 会在每一个子项目执行 clean 命令,然后再执行 deploy 命令。
3.4 Site LifeCycle
Maven Site 插件一般用来创建新的报告文档、部署站点等。
|
|
---|---|
pre-site | 执行一些需要在生成站点文档之前完成的工作 |
site | 生成项目的站点文档 |
post-site | 执行一些需要在生成站点文档之后完成的工作,并且为部署做准备 |
site-deploy | 将生成的站点文档部署到特定的服务器上 |
说明:
- 这里经常用到的是site阶段和site-deploy阶段,用以生成和发布Maven站点,这可是Maven相当强大的功能,Manager比较喜欢,文档及统计数据自动生成,很好看。
3.5 其他说明
3.5.1 构建阶段由插件目标构成
一个插件目标代表一个特定的任务(比构建阶段更为精细),这有助于项目的构建和管理。这些目标可能被绑定到多个阶段或者无绑定。不绑定到任何构建阶段的目标可以在构建生命周期之外通过直接调用执行。这些目标的执行顺序取决于调用目标和构建阶段的顺序。
例如,考虑下面的命令:
clean 和 pakage 是构建阶段,dependency:copy-dependencies 是目标
mvn clean dependency:copy-dependencies package
这里的 clean 阶段将会被首先执行,然后 dependency:copy-dependencies 目标会被执行,最终 package 阶段被执行。
3.5.2 在pom.xml文件中添加阶段文本信息显示
在下面的例子中,我们将 maven-antrun-plugin:run 目标添加到 pre-clean、clean 和 post-clean 阶段中。这样我们可以在 clean 生命周期的各个阶段显示文本信息。
我们已经在 C:\MVN\project 目录下创建了一个 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.companyname.projectgroup</groupId>
<artifactId>project</artifactId>
<version>1.0</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<id>id.pre-clean</id>
<phase>pre-clean</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<echo>pre-clean phase</echo>
</tasks>
</configuration>
</execution>
<execution>
<id>id.clean</id>
<phase>clean</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<echo>clean phase</echo>
</tasks>
</configuration>
</execution>
<execution>
<id>id.post-clean</id>
<phase>post-clean</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<echo>post-clean phase</echo>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
此时如果在控制台输入mvn post-clean
,Maven 将会开始处理并显示 clean 生命周期的所有阶段:
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------
[INFO] Building Unnamed - com.companyname.projectgroup:project:jar:1.0
[INFO] task-segment: [post-clean]
[INFO] ------------------------------------------------------------------
[INFO] [antrun:run {execution: id.pre-clean}]
[INFO] Executing tasks
[echo] pre-clean phase
[INFO] Executed tasks
[INFO] [clean:clean {execution: default-clean}]
[INFO] [antrun:run {execution: id.clean}]
[INFO] Executing tasks
[echo] clean phase
[INFO] Executed tasks
[INFO] [antrun:run {execution: id.post-clean}]
[INFO] Executing tasks
[echo] post-clean phase
[INFO] Executed tasks
[INFO] ------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------
[INFO] Total time: < 1 second
[INFO] Finished at: Sat Jul 07 13:38:59 IST 2012
[INFO] Final Memory: 4M/44M
[INFO] ------------------------------------------------------------------
你可以尝试修改 mvn clean 命令,来显示 pre-clean 和 clean,而在 post-clean 阶段不执行任何操作。
这个对其他LifeCycle也同样适用,这里不在赘述,如有需要参考菜鸟教程-Maven构建生命周期
待续
其他部分暂时不写,以后续上
附上草稿:
1.
部署:将打成的包 放到 服务器上 准备运行
--将jave\js\jsp等各个为见进行筛选、组装,变成一个可直接运行的项目
eclipse中部署在tomcat上的项目可运行
将eclipse中的项目复制到tomecat文件夹却无法运行
但是项目在webappas中直接运行
eclipse中的项目,在部署是 ,会生成一个对应的 部署项目(在wepwebapps中,区别在于,部署项目,没有源码(.java),只有编译后的字节码(.class)
应为二者目录结构不一致,影刺tomcayt中无法直接运行eclipse中复制过来的项目(因为 如果要在tomcat中运行一个项目,则该项目必须严格遵循tomcat的目录结构)
可以使用war包的方式在放到tomcat文件夹中
部署:
通过eclipse通过add-move部署
将web项目打成一个war包,然后将它复制到
自动化构建工具maven:将原材料(jave.js.css.html.图片) -> 产品(可发布)
自动构建:不用手动编译、打包、部署等
eclipase: 半自动化构建工具
jave源代码-.class
编译打包好的jar可以供别人使用
2.
查找jar包的顺序
先本地仓库-->
私服(通常会配置一个nexus)-->
然后中央仓库镜像(copy,减轻中央仓库的压力)-->
最后中央仓库
3.
下载 配置(windows) apache maven
1.配置JAVA_HOME
2.配置MAVEN_HOME或者M2_HOME
3.配置path
%MAVEN_HOME%/bin
4.验证
mvn -v
5.配置本地仓库
setting.xml 中的localRepository 默认${user.home}/.m2/repository
一般修改 直接到文件中取消注释,并修改localRepository值为修改后的仓库路径
4.
使用maven
约定优于配置
硬编码方式: job.setPath("D://abc");
配置方式: job
conf.xml <path>D://abc</path>
约定方式(maven): job 使用默认值 D://abc
maven约定的目录结构(自动生成):
执行代码 --main目录
测试代码 --test目录
Project
-src
--main 程序功能代码
---java 程序代码
---resources 配置代码、资源代码
--test 测试代码
---java 程序代码
---resources 配置代码、资源代码
-pom.xml :项目对象模型 与src同级
maven命令: 需要在pom.xml所在的目录下执行
1.mvn compile 编译命令(只编译main目录中的文件)
编译.java文件->
如果发现缺少jar包,就会查pom.xml->
如果已经配置了依赖,那么就会根据依赖去本地/远程仓库去找->
然后将依赖的jar包下载到本地仓库->
编译完成的文件放在target文件夹下
2.mvn test 测试
3.mvn package 打包成jar/war
4.mvn install 将开发的模块放入本地仓库,供其他模块使用(放入的位置通过g+a+v的方式确定jar包的位置)
5.mvn clean 清理编译出来的文件(target目录)
5.
pom文件结构
<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>org.lanqiao.maven</groupId>
<groupId>域名翻转.大的项目名</groupId> 大项目--子项目
<artifactId>hdfs</artifactId>
<artifactId>项目名</artifactId>
<version>0.0.1-SNAPSHOT</version>
<version>版本号</version>
<packaging>jar</packaging>
<packaging>打包方式?</packaging>
<dependencies>//提供包的信息,以便在本地/中央仓库检索下载
<dependency>
//通过g+a+v的方式定位jar包的位置
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>${hadoop.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>//这是用来限定依赖的使用范围\有效性,可选compile(编译+测试+运行),test(测试),provided(编译+测试)
</dependency>
</dependencies>
</project>
6.
依赖:
在maven项目中,如果要使用一个方式存在的jar或者模块,则可以通过 依赖实现(去本地仓库、中央仓库寻找)
A.jar --> B.jar --> A 中的需要用到/依赖 b中的类
1.依赖的使用范围\有效性,可选
compile(编译+测试+运行),test(测试),provided(编译+测试)
2.依赖排除
A.jar --> B.jar --> A 中的需要用到/依赖 B中的类
将A引入时,会将B引入,但现在不想引入B
A.jar(1.java,2,3,4...)
B.jar(10.java,20,30,40...)
依赖的本质: 1.java调用了10.java中的某个方法
但是当不适用1.java而是使用不依赖任何包的00.jar时,那么其实并不需要引入B.jar
(前提是对这些jar包之间的调用特别熟悉,否则编译无法通过)
或者某些原以为自动回导入的,却没有被导入
<dependencies>
<exclusions>//用此可以排除jar包
<exclusion>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
//不需要版本号
</exclusion>
</exclusions>
</dependencies>
3.依赖的传递性
A->B B->C
要使得A->C : 当且仅当B->C的范围是compile
整合模块 : 依赖于一个仓库(本地/中央)
如果A->B
1.那么需要将B install 到仓库
2.在A的pom.xml中添加 B的坐标到 dependency
7.
在eclipse中创建maven工程
1.配置maven(eclipse会自带,但是一般改成自己的)
eclipse->window->preferences->maven->
A.配置maven版本 installations->选择自己的版本
B.本地仓库可能不一样所以:user setting -> user setting中填入maven 配置文件settings.xml的绝对路径/usr/local/cloud/maven/conf/settings.xml
2.创建maven工程
编辑pom.xml,然后右键maven--update
3.执行maven命令
右键pom.xml -->
run AS - Maven Build...(没有...会默认执行上一次的) -->
Goals 中输入maven 命令 如clear
4.maven生命周期
生命周期和构建的关系:
假设执行顺序a b c d e
执行后面的命令会执行前面的命令
例如执行d时候 会把 abc都执行一次
生命周期包含三个阶段
clean lifecycle:清理
pre-clean clean post-clean
default lifecycle: 默认(常用)
site lifecycle: 站点
pre-site site post-site site-deploy
8.
<build>
<plugins>
<plugin>
<!-- 第一步 在项目的pom.xml文件中修改默认的jar插件 -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.1</version>
<configuration>
<archive>
<manifest>
<!--运行jar包时运行的主类,要求类全名-->
<mainClass>com.xxx.xxx</mainClass>
<!-- 是否指定项目classpath下的依赖 -->
<addClasspath>true</addClasspath>
<!-- 指定依赖的时候声明前缀 -->
<classpathPrefix>./lib/</classpathPrefix>
<!--依赖是否使用带有时间戳的唯一版本号,如:xxx-1.3.0-20121225.012733.jar-->
<useUniqueVersions>false</useUniqueVersions>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<!-- 接着我们还要配置maven的maven-dependency-plugin插件
把当前项目的所有依赖放到target目录下的lib文件夹下 -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<!--已存在的Release版本不重复copy-->
<overWriteReleases>false</overWriteReleases>
<!--已存在的SnapShot版本不重复copy-->
<overWriteSnapshots>false</overWriteSnapshots>
<!--不存在或者有更新版本的依赖才copy-->
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>