项目依赖管理
在项目合作开的时,我们是如何进行项目依赖管理的呢?
我们通常会在新建项目的时候,同时建立一个lib
目录,在其中放着项目所依赖的各方类库
,这样提交到SVN
之后, 每个开发人员检出项目到本地,得到项目的工作副本
,这样所有开发人员就会持有统一的项目依赖了。这样有2个
比较明显的问题。
管理中的问题
依赖冗余
随着项目的增多,模块的增多,这种方式就会有问题。很多模块都会引用相同的依赖,当每个模块都把自己的依赖提交到SVN,那么相同的依赖就会占用服务器SVN的Repository很大的空间,造成空间浪费
。
版本问题
同时,如果一个项目中依赖的版本和另一个项目依赖的版本不一致。比如这个项目依赖hibernate2.x,而另一个可能依赖hibernate3.x, 当合并两个项目发布的时候, 可能因为这种依赖类库详细版本信息的缺失
,造成问题。
解决办法
为了解决以上依赖管理过程中出现的问题以及我们项目中遇到的其他类似问题, 我们寻求出一途径:各个项目只要通过统一的依赖描述文件
(pom.xml
)来指定自己需要的依赖就可以, 而不用自己来管理真正的依赖库,因为所有的项目都使用同一个中央依赖库
(中央仓库
), 所以即使各个项目中有相同的依赖
, 也不会出现依赖冗余的问题。Maven
正是我们寻求的,能解决此问题的工具。
Maven是什么
基本概念
Maven
是基于POM
(project object model,即项目对象模型
)的跨平台
的项目管理工具,主要服务于基于JAVA平台的项目构建,依赖管理和项目信息管理。
- 项目构建
清理
、编译
、测试
、报告
、打包
、部署
; - 依赖管理
自动下载
,统一依赖管理
; - 信息管理
项目名称描述
,开发人员信息
,开发者信息
。
PS: 测试报告
存放在target
文件夹下。
优势
如果没有Maven,你可能不得不经历下面的过程:
- 使用jar包时,需要去官网下载,譬如:如果使用了spring,去spring的官网下载jar包;
- 当某些jar包有依赖的时候,还要去下载对应的依赖jar包;
- 当jar包依赖有冲突时,不得不一个一个的排查;
- 执行构建时,需要使用ant写出很多重复的任务代码;
- 当新人加入开发时,需要拷贝大量的jar包,然后重复进行构建。
而maven的优势就是:
- 项目jar包的依赖管理:仅仅通过jar包的几个属性,就能确定唯一的jar包,在指定的文件pom.xml中,只要写入这些依赖属性,就会自动下载并管理jar包;
- 项目自动化编译部署:清理—>编译—>测试—>打包—>部署;
- 项目的插件管理。
Maven的配置文件
如果使用过Ant都知道Ant是通过build.xml执行构建任务的,Maven中是通过pom.xml
来执行任务.
POM,project object model,即项目对象模型,它通过这个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.h3c</groupId>
<artifactId>mavenLearning</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>xxxx</name>
<packaging>war</packaging>
</project>
第一行指定了文档的XML版本
和编码
;
第二行即每个pom.xml的核心元素——project
;
project下面有几个子元素,这几个子元素一般是每个项目都会使用到的:
modelVersion
这个元素指定了POM的版本
(Maven2或者Maven3 都只能是4.0.0);groupId
是项目组的ID
,一般是com.公司组织名.项目名;artifactId
是该项目在项目组中ID
,比如当前的项目是项目组的一个服务链项目,就可以叫做serviceChain;version
是项目的版本号
,用于维护项目的升级和发布;name
一般没有实际的用处,只是用于标识
该项目;packaging
项目打包方式
,常有jar
,war
,pom
等,缺省下为jar
比较重要的参数是groupId
、artifactId
、version
,这三个属性确定唯一
的一个项目。
Maven如何管理jar包
Jar包坐标
关于jar包的坐标,maven是通过groupId,artifactId,以及version确定一个唯一的jar包。
例如,最常使用的Junit
的声明就是如下:
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<scope>
这是声明的范围,不同的生命周期所要求的范围是不一样的。
Maven仓库
在Maven中会涉及到几种仓库:
工作空间
,即我们的项目工程,这里面放着pom.xml文件,这个pom.xml就是maven的配置文件;本地仓库
,本地仓库用于存放jar包,其实Jar包并不是直接放入工作空间的,它是存放在本地仓库,然后在执行发布打包的时候,添加依赖路径;私库
:私库是使用者自己搭建的maven仓库,用于缓解频繁从外网下载jar包资源的压力。而且使用私库作为缓存层,也相对安全一些;共享仓库
:一般所说的中央仓库或者一些常用的镜像网站都属于这种,国内比较著名的oschina以及163都是不错的maven仓库。
Maven下载jar包的过程
当我们在pom中声明了依赖关系后,参考上面的图:
- Maven在执行相关的任务时,会先去本地仓库查看是否有该资源,如果有的话,判断版本是否正确,如果一切都没问题则直接使用;否则,执行下一步;
- Maven会去配置的共享仓库中查找,如果找到就拷贝到本地仓库中;找不到则会给出相关的提示;
- Maven在本地如果搭建了私库,则会去私库中查找,找到就拷贝到本地仓库;找不到就会去共享仓库中查找,然后放入私库和本地库。有了私库,局域网内的开发者可以共享依赖,就不用每个人都去外网下载jar包,浪费带宽了。
Maven的目录结构介绍
bin
:该目录下同JDK一样,主要是Maven的运行脚本,这些脚本用来配置Java命令,准备好classpath和相关Java系统属性,然后执行Java命令。mvn.bat是基于Windows的脚本。在CMD中每次输入一条MVN的命令都是在调用并执行这些脚本。该目录还有一个文件名为m2.conf,它是classworlds的配置文件。
boot
:该目录只有一个文件plexus-classworlds-2.5.1.jar。他是一个类加载器的框架,相对于JDK中的类加载器,它提供了更丰富的语法以方便配置,Maven使用该框架架在自己的类库。
conf
:该目录包含了一个非常重要的文件setting.xml。配置该文件就能在Project中定制Maven的行为。
lib
:包含了所有Maven运行时需要的Java类库以及用到的第三方以来。
LICENSE
:记录了Maven的软件许可证。
NOTICE.txt
:记录了Maven所包含的第三方软件。
README.txt
:包含了Maven的简介以及简要指令等.
代理配置
我们没有搭建私服(私库),Maven工程需要的jar包需要联网下载,在setting.xml
配置文件中配置代理,即可下载需要的jar包。
<proxies>
<proxy>
<id>optional</id>
<active>true</active>
<protocol>http</protocol>
<username>xxxx</username>
<password>xxxx</password>
<host>xxx</host>
<port>xxx</port>
<nonProxyHosts>local.net|some.host.com</nonProxyHosts>
</proxy>
</proxies>
在<settings>
标签中添加如上代码,说明如下:
proxies
中可以配置多个proxy,但是默认第一个proxy生效。active
中的TRUE表示该代理目前生效状态。- http协议、主机地址、端口不在赘述。
- 用户名密码按需配置即可。
nonProxyHost
表示不需要代理访问的地址。中间的竖线分隔多个地址,此处可以使用星号作为通配符号。
本地仓库配置
本地仓库
,顾名思义,就是Maven在本地存储构件的地方。
注:maven的本地仓库,在安装maven后并不会创建,它是在第一次执行maven命令的时候才被创建
maven本地仓库的默认位置:无论是Windows还是Linux,在用户的目录下都有一个.m2/repository/
的仓库目录,这就是Maven仓库的默认位置
如何更改maven默认的本地仓库的位置:这里要引入一个新的元素:localRepository
。
<localRepository>E:\MAVEN</localRepository>
远程仓库配置
远程仓库中最核心的中央仓库
(还有私服和其它公共库),中央仓库是默认的远程仓库,maven在安装的时候,自带的就是中央仓库的配置。所有的maven项目都会继承超级pom,具体的说,包含了下面配置的pom我们就称之为超级pom
。
中央仓库包含了绝大多数流行的开源Java构件,以及源码、作者信息、SCM、信息、许可证信息等。一般来说,简单的Java项目依赖的构件都可以在这里下载到。
<repositories>
<repository>
<id>central</id>
<name>Central Repository</name>
<url>http://repo.maven.apache.org/maven2</url>
<layout>default</layout>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
Maven的生命周期及阶段
生命周期
Maven中有三大生命周期
,他们相互独立,分别是:
clean
清理;default
构建;site
建站;
一般来说,clean
和default
比较常用。
阶段
每个生命周期又有不同的阶段,阶段按顺序执行,并且可以指定执行结束的阶段。构建的时候,会依次从最上面的阶段执行到指定的那个阶段。
比如,clean有3个阶段:
pre-clean
执行清理前要完成的工作clean
清理上一次构建生成的文件post-clean
执行清理后需要完成的工作
当我们输入mvn clean
的时候,执行的是pre-clean
和clean
两个阶段。
default的阶段比较多:
- validate
- initialize
- 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
- tet
- prepare-package
- package
- pre-integration-test
- integration-test
- post-integration-test
- verify
- install
- deploy
看名字大概就能理解,当执行mvn install
的时候,实际会执行validate
-> initialize
->… -> verify
-> install
等二十几个阶段。
为了操作方便,不同的生命周期可以在一起执行,比如mvn clean install
,会先
执行clean
的阶段,再
执行install
的阶段。
在IDE
开发环境中,当我们Run as
的时候,就可以执行maven clean
进行清理,或者执行maven install
进行构建,也可以执行maven build
同时执行clean
和install
两个任务.
Maven工程结构介绍
一般的Maven
项目会包含这样一个目录树
:
project
|-src–main–java–你的源代码
|–main–resource:资源文件
|–test–java–单元测试代码
|–test– resource–单元测试代码相关资源文件
|–target–编译出的文件和jar包
|–pom.xml–项目信息以及任务定义
“约定优于配置(Convention over Configuration)”,maven提供了约定
的项目的目录结构,自动创建
项目目录,提高开发效率。
Maven 集成Tomcat7插件
Maven Tomcat插件现在主要有两个版本,tomcat-maven-plugin
和tomcat7-maven-plugin
,使用方式基本相同。
在pom.xml中加入节点:
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.1</version>
<configuration>
<port>9090</port>
<path>/mavenLearningTest</path>
<uriEncoding>UTF-8</uriEncoding>
<server>tomcat7</server>
</configuration>
</plugin>
</plugins>
</build>
path
是访问应用的路径。port
是tomcat的端口号
(一般在tomcat—conf-- server.xml
中修改)。uriEncoding
URL
按UTF-8
进行编码,这样就解决了中文参数乱码
。Server
指定tomcat名称
。
选择pom.xml
文件,击右键——>选择 Run As
——> Maven build
,在Goals
中填写:tomcat7:run
(若填的是tomcat:run
,默认调用的是tomcat-maven-plugin
,此时pom
配置文件中也得修改)
几个常用的Goal
命令 | 描述 |
---|---|
tomcat7:deploy | 部署一个web war包 |
tomcat7:reload | 重新加载web war包 |
tomcat7:start | 启动tomcat |
tomcat7:stop | 停止tomcat |
tomcat7:undeploy | 停止一个war包 |
tomcat7:run | 启动嵌入式tomcat ,并运行当前项目 |
下一篇中将介绍下如何使用Maven搭建SpringMVC项目