项目管理利器-Maven
现在流行的有Maven、Ant、gradle这些优秀的项目管理和构建工具,它让我们更加方便的管理和构建我们的项目。
一.Maven快速入门
1.maven介绍
Maven是基于项目对象模型(POM),可以通过一小段描述信息来管理项目的构建、报告和文档的软件项目管理工具。
简单来说,Maven可以帮助我们更有效的来管理项目,它也是一套强大的自动化工具,覆盖了编译、测试、运行、清理、打包和部署整个项目构建的周期,它提供了一个仓库的概念,统一帮助我们管理项目所依赖的第三方的jar包,最大可能的由于环境配置不同所产生的在你的电脑上能运行,而在我的电脑上不能运行的问题,目前有很多著名的开源项目都在使用Maven进行管理,如Struct2、Hibernate。
2.maven环境搭建
我们从maven官网http://maven.apache.org/download.cgi下载maven

下载后将其解压

bin目录包含mvn的运行脚本,输入mvn就会调用这些脚本。

m2.conf是一个配置文件。

boot目录包含一个类加载器的框架,Maven使用它来加载自已的类库。

conf下面是一些配置文件,比如settings.xml我们以后会经常用到。

lib目录包含Maven所需的所有类库,除了Maven自身的,还包含了一些第三方依赖的类库。
配置Maven环境变量,首先配置M2_HOME

然后在Path中增加Maven的配置如下。

此时,打开cmd命令提示符,输入mvn -v可以查看到maven的版本号、java的版本号、操作系统信息,如果能查看到,说明安装成功了。

3.hello maven实战
创建一个maven版的hello world,Maven的项目结构
src -main -java -package -test -java -package -resources
然后在本机电脑上的E盘下的study下新建code目录,下面再建maven01目录,然后在maven01目录下按上面的目录结构建立相应的包和类。
HelloWorld.java
package com.bijian.maven01.model; public class HelloWorld { public String sayHello() { return "Hello World!"; } }

这时,我们需要一个pom.xml文件来管理我们的项目,可以从struct2的源代码文件中找到,如struct2-core-2.2.3.jar,将其打开,在META-INF\maven\org-apache-structs\struct2-core中可以找到pom.xml文件,将其拷贝出来,然后把多余的代码删除,放到src同步目录中,编辑好后内容如下:
<?xml version="1.0" encoding="UTF-8"?> <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.bijian.maven01</groupId> <artifactId>maven01-model</artifactId> <version>0.0.1SNAPSHOT</version> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.10</version> </dependency> </dependencies> </project>
说明:modelVersion代码maven,这里4.0.0是固定的,groupId的值就是项目的包名,artifactId的值是模块名,version的值是版本,dependencies是导入依赖。
在cmd窗口,进入E:\study\code\maven01目录,输入mvn compile命令编译项目,输出"BUILD SUCCESS"表示编译成功。

再输入mvn test命令,可以看到执行了单元测试且没有报错。

此时,我们可以看到在maven01目录下产生了target目录。

在classes下存放的就是我们编译所生成的字节码文件,surefire-reports下面存放的就是我们所生成的测试报告。
再输入mvn package命令,成功后将会在target目录下生成一个maven01-model-0.0.1SNAPSHOT.jar


二.maven基础知识
1.maven常用的构建命令
mvn -v:查看maven版本
mvn compile:编译
mvn test:测试
mvn package:打包
mvn clean:删除target
mvn install:安装jar包到本地仓库中
a.mvn clean
运行mvn clean命令后,它将我们的根目录下的target目录删除了。它就是用来删除maven所生成的目标文件的。

b.mvn install
在code目录新建maven02项目(建的方法同maven01),pom.xml、Speak.java和SpeakTest.java如下:
Speak.java
package com.bijian.maven02.util; import com.bijian.maven01.model.HelloWorld; public class Speak { public String sayHi() { return new HelloWorld().sayHello(); } }
SpeakTest.java
package com.bijian.maven02.util; import org.junit.*; import org.junit.Assert.*; public class SpeakTest { @Test public void testSayHi() { Assert.assertEquals("Hello World!", new Speak().sayHi()); } }
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <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.bijian.maven02</groupId> <artifactId>maven02-model02</artifactId> <version>0.0.1SNAPSHOT</version> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.10</version> </dependency> </dependencies> </project>
此时,进入maven02根目录,输入mvn compile命令执行并没有成功。

提示com.bijian.maven01.model不存在,通常我们可以把包含这个类的jar包加到classpath中,maven提供了更为方便的方法。那就是进入maven01项目的根目录,执行mvn install命令,这个命令可以将包含HelloWorld类的jar文件发布到本地仓库中,然后再修改maven02下的pom.xml文件,将maven的坐标依赖进来,如下所示:
<?xml version="1.0" encoding="UTF-8"?> <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.bijian.maven02</groupId> <artifactId>maven02-model02</artifactId> <version>0.0.1SNAPSHOT</version> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.10</version> </dependency> <dependency> <groupId>com.bijian.maven01</groupId> <artifactId>maven01-model</artifactId> <version>0.0.1SNAPSHOT</version> </dependency> </dependencies> </project>
此时,我们再进入maven02项目根目录,输入mvn compile命令。

说明:我们用mvn compile编译源代码,在编译过程中,如果程序依赖了其它的包,会去pom.xml中查找是否有依赖该依赖包的坐标,找到坐标后,会去本地仓库中查找,如果有该jar包,就会将该jar包加到项目的classpath中,如果没有该jar包,就会去公网的maven中中央仓库中查找、下载,并放到项目的本地仓库中供其使用。
2.自动创建目录骨架
archetype插件用于创建符合maven规定的目录骨架。
在code目录下创建maven03目录,然后进入cmd窗口,输入命令:mvn archetype:generate,然后会要求选择archetype(我这里输入7)、输入groupId(我这里输入com.bijian.maven03)、输入artifactId(我这里输入maven03-service)、输入version(我这里输入1.0.0-SNAPSHOT)、package(我这里输入com.bijian.maven03.service)回车。

这时我们的目录骨架就创建好了,可以到目录下查看如下:

当然,除了这种方式,还有另一种方式,那就是一次性设置完了所有的属性,如:mvn archetype:generate -DgroupId=com.bijian.maven04 -DartifactId=maven04-demo -Dversion=1.0.0SNAPSHOT -Dpackage=com.bijian.maven04.demo

maven自动给我们生成的maven04-demo文件夹,如下所示:

创建目录的两种方式:
a.archetype:generate,按照提示进行选择
b.archetype:generate -DgroupId=组织名,公司网址的反写+项目名 -DartifactId=项目名-模块名 -Dversion=版本号 -Dpackage=代码所存放的包名
3.maven中的坐标和仓库
任何一个依赖、插件、项目构建的输出都可以被称之为构件,所有构件均通过坐标作为其唯一标识,其中groupId、artifactId和version组成项目的基本的坐标,在maven中任何构件都是由这些坐标来进行唯一标识,在这里给大家一些建议:在创建maven项目时,java的包名应该与pom.xml中定义的groupId和artifactId相吻合,这样看起来就更加的清晰、符合逻辑,也更方便搜索。
仓库就是用来管理项目的依赖的,它分为两种:本地仓库和远程仓库,本地仓库中找不到相应的jar包,就会去maven的远程中央仓库查找,如果远程的中央仓库也找不到,就会报错。maven默认提供了一个全球仓库的地址,我们可以在安装目录的lib目录下找到maven-model-builder-3.6.0.jar,将其打开,可以找到pom-4.0.0.xml文件,它是maven为我们提供的超级pom.xml,所有maven项目都会继续这个pom.xml

我们将其打开,Central Repository对应的url就是默认的全球中央仓库的地址。

id:中央仓库的唯一的标识
name:中央仓库名称
url:中央仓库url
layout:default表示的是默认的布局
snapshots下的enabled:false表示禁止下载快照版本的构件
中央仓库包含绝大多数开源的java项目,基本上我们平时做开发所用到的开源框架,在这里都可以找得到。

镜像仓库:Maven中央仓库的服务器都是位于国外的,有时因为一些原因导致无法访问外网,不过好在国内有它的镜像仓库,这样就可以直接访问镜像仓库,那么,如果修改镜像仓库的位置呢?打开maven安装路径下的conf目录下的settings.xml文件,如下所示:

更改仓库位置:maven从远程仓库中下载构件默认是存在在当前用户目录的.m2/repository下,但是对我们来说,我们一般不要将仓库放到C盘中,因为重装系统或其它原因会丢失,下面我们来更改一下仓库的默认路径为E:\Maven\repo,如下所示:

并将安装路径下的setting.xml复制到E:\Maven中,这样以后我们更新Maven版本就不需再次修改settings.xml

再进入maven01项目,重新执行mvn compile、mvn install命令,可以看到构建出来的包放到了我指定的本地仓库中。

4.在Eclipse安装maven插件以及创建maven项目
首先看Eclipse是否有自带安装Maven,即在Window->Preferences打开看是否有Maven。

我这里的Eclipse有安装Maven插件,如没有插件,可网上下载,然后将其拷贝到eclipse下的dropins目录中重启Eclipse,可能还要在eclipse根目录下的eclipse.ini中新增如下配置:

PS:Eclipse默认用的是jre,由于Eclipse运行在JRE之前,而maven是运行在JDK之上的,需要将其改到JDK下的jre(即JDK私有的JRE),有些环境下可能会提示找不到tools.jar,也是由于Eclipse默认是运行在JRE之上,而Maven的插件功能是需要用到tool.jar,而tool.jar是在JDK的lib目录下,而Eclipse默认指向的JRE并没有tool.jar,所以需要为Eclipse修改指定到JDK私有的JRE。

然后更改maven默认的配置
a.添加本地Maven

b.修改User Settings为本地settings.xml

c.新建一个maven项目



可以看到,pom.xml内容和我们之前手工创建的基本是一样的。

右键pom.xml文件,Run As->Maven build...

在弹出的框中输入compile,点击“Run”运行,

提示如下信息。

我们需在JRE中进行如下配置。

此时,我们重新右键pom.xml文件,Run As->Maven build...,输入compile运行成功如下所示:

右键pom.xml文件,Run As->Maven build...,输入package运行,提示jar包构建成功。

进入项目的根目录也可以看到打出来的jar包,且可以看到已成功构建出class文件、测试报告。

5.maven的生命周期和插件
完整的项目构建过程包括:清理、编译、测试、打包、集成测试、验证、部署
maven定义了三套独立的生命周期:clean(清理项目)、default(构建项目)、site(生成项目站点)
maven生命周期:clean、compile、test、package、install,package运行时,会自动先运行compile、test。
a.clean清理项目又分成三个阶段
pre-clean:执行清理前的工作
clean:清理上一次构建生成的所有文件
post-clean:执行清理后的文件
b.default构建项目(最核心)
compile、test、package、install
c.site生成项目站点
pre-site:在生成项目站点前要完成的工作
site:生成项目的站点文档
post-site:在生成项目站点后要完成的工作
site-deploy:发布生成的站点到服务器上
5.maven的插件

单单对于Maven而言,它并没有什么执行功能,它的下载包也非常的小,Maven中所有的命令都是通过调用命令来实现的,Maven有很多插件,在maven官网上,可以看到。
我希望在运行package命令时,可以将它的源码进行打包,所以我们要绑定source到生命周期的package阶段,编译pom.xml增加如下插件配置:

完整的pom.xml内容如下:
<?xml version="1.0" encoding="UTF-8"?> <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.bijian.demo</groupId> <artifactId>hi</artifactId> <version>0.0.1-SNAPSHOT</version> <name>hi</name> <!-- FIXME change it to the project's website --> <url>http://www.example.com</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.7</maven.compiler.source> <maven.compiler.target>1.7</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-source-plugin</artifactId> <version>2.4</version> <executions> <execution> <phase>package</phase> <goals> <goal>jar-no-fork</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>
此时,右键pom.xml文件,Run As->Maven build...,输入clean package运行成功如下所示:

再打开项目的根目录下的target文件夹,可以看到打出了源代码的jar包。

6.pom.xml常用元素介绍
pom.xml是maven项目的核心管理文件,用于项目描述、组织管理、依赖管理和构建信息的管理,pom.xml中包含许多的标签。
首先,pom.xml最上面包含有POM一些约束的信息。
modelVersion:是一个必须的元素,值是固定的版本,指定了当前pom的版本
然后是坐标信息,由goupId、artifactId、version、packaging,goupId是主项目的标识,用来定义当前maven属于哪个实际的项目的,是由反写的公司网址+项目名来组成的。artifactId表示一个模块的标识,是实际项目中的一个模块,一般由项目名+模块名来标识,version表示当前项止的版本号,一般由三个数字来表示的,第一个0表示大版本号,第二个0表示分支版本号,第三个0表示小版本号。0.0.1snapshot给示快照版,alpha内部测试版本,beta公测版本,release版本是稳定版本,GA正式发布。packaging表示打包的方式,不指定默认是jar,还可以打包成其它类型,如war、zip、pom。
在这里需要注意的是,Maven项目和我们实际项目不是一一对应的关系,Maven项目体现的是一个模块化的概念,因此,一个实际项目可能会被划分成很我个模块。
name:项目描述名
url:项目的地址
description:项目的描述
developers:开发人员列表
licenses:允可证的信息
organization:组织信息
dependencies:依赖列表,下面可以包含多个依赖项。以dependecny标识,其下的scope表示依赖范围,如test表示这个jar只在测试的范围内有用,在主代码中引用就会报错。其下的optional用来设置依赖是否可选,默认是false(是继承的),如果是true则表示子项目必须显示的引入该依赖。exclusions用来排除依赖传递列表,如我们需要用到spring,但spring还引用到了其它很多的jar,如果我只用到spring.jar,那么就可以用exclusion来排除。
dependencyManagement:依赖的管理,其下是dependencies,再其下是dependency,这里的依赖并不会引入到实际的依赖中,主要用在定义在父模块中,用于子模块继承用的。如我们之前的多个项目都依赖了junit,就可以抽像出来一个父类的模块,然后在父类模块中对junit进行定义,其它子模块直接继承它就OK了。
build:为我们的构建行为提供支持,我们经常用的是里面的plugins,也就是插件的列表,如之前用到的source插件。
parent:通常用于子模板中对父模板pom的继承。
modules:用来聚合运行多个的maven项目,如果我们有很多的maven模块需要编译的话,我们之前的办法是一个一个编译,使用modules就可以在这里定义多个module,在一起进行编译。





7.依赖范围

Maven为我们提供了三种classpath,分别是编译、测试、运行。junit使用的scope是test,表明junit只存在于测试的classpath中,也就是存在于测试的范围,scope就是用来控制依赖和三种classpath的关系的。scope有如下六种值:
compile:默认的范围,编译测试运行都有效
provided:在编译和测试时有效,如servlet的jar,在运行时无需加入,因为Web容器已经包含了这些API,加进去会产生冲突
runtime:在测试和运行时有效
test:只在测试时有效
system:与本机系统相关联,可移植性差
import:导入的范围,它只使用在dependencyManagement中,表示从其它的pom中导入dependency的配置


8.依赖传递
A依赖B,B又依赖C,A其实也依赖C,即A编译时也会把C引入进来。如果A不想依赖C,则需用exclusionss标签来做排除。

发现项目显示依赖的JDK是1.5的,而实际上依赖的是1.7的,我们可以右击修改

但这样一个一个修改,比较麻烦,可以直接修改setttings.xml中的profiles下增加如下代码:

这时我们再在Eclipse中新建项目,JDK的版本显示就正确了。
9.依赖冲突
如果有A和B有依赖不同版本的相同构件,那么对于依赖A和B的C来说,到底依赖的是哪个版本的构件?这里有两条原则:
a.短路优先

b.先声明先优先
如果路径长度相同,则谁先声明,先解析谁。这里的先声明,是指在pom.xml中写的先后顺序。
10.聚合和继承
如果在maven中,想将多个项目进行install,将其安装到本地仓库中必须依次执行install命令,maven有一种方式将其放到一起运行,这种方式称之为聚合。
实例:
原来有建hongxing-bge、hongxing-nage、hongxing-shanji三个maven项目,再创建hongxing-aggreation项目,将其packaging的配置值改为pom。

建好后,右键Run As->Maven build...,输入clean install,点击运行。可以看到控制台的日志输出了三次构建,分别生成hongxing-bge.jar、hongxing-nage.jar、hongxing-shanji.jar并安装到本地的仓库中。
在这几个项目中,我们每个项目中都配置有junit的依赖,我们新建一个maven项目hongxing-parent,将junit放到此项目的pom.xml中的dependencyManagement下,如下所示:

这时,我们可以修改其它项目的pom.xml,新增parent标签,引入父类标签。

三.Maven建立web项目
新建Maven项目,Archetype选择maven-archetype-webapp


点击“完成”即创建了一个maven的web项目,结构如下:

index.jsp报错是因为没有servlet依赖,我们需要pom.xml中添加servlet的依赖,如下所示:

添加servlet依赖后, index.jsp文件就没有报错了。
选中Java Resources,右击选择“New”->Source Folder

分别新建如下四个Source Folder。

检查class文件的输出路径。

确保输出在target相应的目录中。

然后需要将项目转换成web项目,在项目上右键->Properties,点击Project Facets。

将“Dynamic Web Module”勾选上,点击“OK"按钮。
接下来修改部署时的默认配置,在项目上右键->Properties,点击Deployment Assembly。

将测试相关的Remove掉,点击“OK"。
这样一个Web相关项目就创建完成了,接下来我们使用package命令将其打成war包,将其拷贝到支持的web容器中,我们的项目就可以在浏览器中进行访问了,首先我们在build标签中添加jetty插件,如下所示:

然后右键项目,Run As->Maven build...,输入jetty:run运行。

在浏览器中输入:http://localhost:8080,如下所示,表明我们的jetty插件也安装成功了。

如果我们想在打包阶段就运行,可以使用executions标签,如下所示:

然后右键项目,Run As->Maven build...,输入clean package运行,也能正常启动起来。
如果要用tomcat做为容器来运行,也相当容易,进入maven官网,找到Maven Plugin

点击Version 2.2后,将如下红框内容复制到项目中。


然后右键项目,Run As->Maven build...,输入clean package运行,控制台输出如下内容表明在tomcat中启动成功。

在浏览器中输入http://localhost:8080/webdemo/,如下所示表示访问也是OK的。

posted on 2019-03-17 21:59 bijian1013 阅读(305) 评论(0) 收藏 举报
浙公网安备 33010602011771号