目前工作中使用的是Maven进行Java代码的项目管理,Maven主推的是集中式的项目管理方式,就是将Web工程中依赖的jar包放在统一路径下进行集中式的管理。
下面简单说下Maven管理的工程的pom文件的常见使用方法和规则,Maven管理的项目依赖是以xml文件格式(文件名:pom.xml)放在工程的根目录下面的。首先我们看一个简单的pom文件来了解下基本的pom.xml格式,见下面xml文件内容。
</pre><p></p><p><pre name="code" class="html"><?xml version="1.0" encoding="UTF-8"?>
<!-- Maven 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/maven-v4_0_0.xsd">
<!-- 标记工程的父工程, 可以不填写 -->
<parent>
<groupId>com.sample</groupId>
<artifactId>parent</artifactId>
<version>1.0.1</version>
</parent>
<!-- 描述本工程的信息:groupId和artifactId,名字,打包方式() ,及版本-->
<modelVersion>4.0.0</modelVersion>
<groupId>com.alibaba.webx</groupId>
<artifactId>tutorial1</artifactId>
<name>My Simple Webx Application</name>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<!-- 文件中后面需要用的一些变量,放在这里是为了突出和管理 -->
<properties>
<java.version>1.6</java.version>
<java.encoding>UTF-8</java.encoding>
<webx-version>3.2.4</webx-version>
</properties>
<!-- 工程如果有多个子工程构成,则需要声明子工程的信息 -->
<modules>
<module>sample-biz</module>
<module>sample-common</module>
<module>sample-config</module>
</modules>
<!-- 工程依赖的二方或三方包信息 -->
<dependencies>
<dependency>
<groupId>com.alibaba.citrus</groupId>
<artifactId>citrus-webx-all</artifactId>
</dependency>
</dependencies>
<!-- 一般有多个子工程时在这里声明第三方的依赖信息,子工程在依赖的时候就不需要声明依赖的版本信息,这也是maven集中式的项目管理理念的一个体现。避免多个子pom依赖的jar版本冲突,并同统一管理依赖版本信息,一般子pom文件中不需要这个标签 -->
<dependencyManagement>
<dependencies>
<!-- ================================================= -->
<!-- Webx框架依赖 -->
<!-- ================================================= -->
<dependency>
<groupId>com.alibaba.citrus</groupId>
<artifactId>citrus-webx-all</artifactId>
<version>${webx-version}</version>
</dependency>
<!-- ================================================= -->
<!-- 日志及相关依赖(用slf4j+logback代替jcl+log4j) -->
<!-- ================================================= -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.5</version>
<exclusions>
<exclusion>
<groupId>com.sample.forest</groupId>
<artifactId>smaple.client</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencyManagement>
<!-- 工程文件打包或测试的时候需要的一些插件配置 -->
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
在前面的简单的pom.xml文件中,基本每部分的内容我都做了备注解释每个标签的意义及使用场景(主要是子工程和父工程中),现在主要说明下其中的附加功能和常见的问题。
1.依赖范围 scope 标签
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.5</version>
<scope>test</scope>
</dependency>
<scope>标签值的选项有:
- compile:默认的
- test:运行单元测试引入依赖,打包时不会依赖
- provided:编译时依赖,不会被打包。如依赖容器的某个jar,只有运行的时候才使用到,编译期间无需应用容器,这种场景下使用这个值
- runtime:运行时依赖
- system:指定为这个值的时候需要添加依赖的jar的具体路径,使用场景和配置见 http://agile-boy.iteye.com/blog/56698
2.依赖版本限制
<version>[3.8,4.0)</version> 要求的依赖版本>=3.8且<4.0
<version>[,3.8.1]</version> 要求的依赖版本<=3.8.1
<version>[3.8.1]</version> 要求必须是3.8.1版本,如果不是的话会构建失败,提示版本冲突。原来的写法<version>3.8.1</version>的意思是所有版本都可以,但最好是3.8.1
3.间接依赖的排除
比如:依赖的jar里面间接依赖一个不想依赖的工程 smaple.client ,这个时候可以主动排查间接依赖的jar,具体配置如下
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.5</version>
<exclusions>
<exclusion>
<groupId>com.sample.forest</groupId>
<artifactId>smaple.client</artifactId>
</exclusion>
</exclusions>
</dependency>
4.maven的jar版本选择策略
- 优先选择主pom中dependencyManagement声明的版本
- 如果没有声明则选择依赖路径最短的jar版本
- 如果路径相同有严格区间限制的优先
- 若路径相同且无严格区间限制则先入为主。
总结:maven的项目依赖管理极大的解放了开发的劳动力,让开发将主要精力放在业务开发和业务逻辑实现上;但是最大的问题就是jar冲突导致的各种NoSuchMethod,ClassNotFound等等类似的错误,只能靠开发在引入新的jar包时注意避免引入冲突的jar。另外根据maven的jar版本选择策略,工程中明确使用的jar最好指定版本,而不是依赖于已有的间接依赖。