- 浏览: 1594275 次
- 性别:
- 来自: 苏州
文章分类
最新评论
-
payton321:
dao,util,servie,基础模块应该是maven项目, ...
Maven最佳实践:划分模块 -
AdrainHuang:
深有体会,我这边已经 给项目坑死了,依赖关系太复杂,基本没人敢 ...
Maven最佳实践:管理依赖 -
远方_张涛:
赞赞赞,生动有趣还说明问题
Maven最佳实践:版本管理 -
smartdog:
新的网站访问不了啊~~博主快更新
再见JavaEye -
smartdog:
言简意赅,厉害
Maven最佳实践:遵循约定
“一法度衡石丈尺,车同轨,书同文字” —— 《史记·秦始皇本纪》
标准的重要性不用我过于强调,想象一下如果不是所有人都基于HTTP开发WEB应用,这个世界会乱成怎样。IE,FF等浏览器之间的差别已经让很多开发者头痛不已。JAVA成功的原因之一就是由于它能屏蔽大部分操作系统的差异,XML流行的原因之一是所有语言都接受它。Maven当然还不能和这些既成功又成熟的技术相比,但所有Maven的用户都应该清楚,Maven提倡的是“约定优于配置(Convention Over Configuration)”,这是Maven最核心的理念之一。
Maven是服务于项目生命周期的(有些人说它是build工具,但build只是生命周期的一部分),它试图抽象整个项目生命周期,实际上它也做到了。几乎所有的项目都离不开Mave所定义的生命周期阶段(clean compile test package site...)。不止如此,基于这些阶段,Maven通过插件提供了绝大部分的默认实现,它们不用做任何配置(或者仅需要很少的配置),就能帮你完成你的工作。
先看一个简单的基于Ant的build.xml文件。(在Maven之前,你在使用Ant,对吧?如果连Ant都没用,那就更糟了)
<project name="my-project" default="dist" basedir="."> <description> simple example build file </description> <!-- set global properties for this build --> <property name="src" location="src/main/java"/> <property name="build" location="target/classes"/> <property name="dist" location="target"/> <target name="init"> <!-- Create the time stamp --> <tstamp/> <!-- Create the build directory structure used by compile --> <mkdir dir="${build}"/> </target> <target name="compile" depends="init" description="compile the source " > <!-- Compile the java code from ${src} into ${build} --> <javac srcdir="${src}" destdir="${build}"/> </target> <target name="dist" depends="compile" description="generate the distribution" > <!-- Create the distribution directory --> <mkdir dir="${dist}/lib"/> <!-- Put everything in ${build} into the MyProject-${DSTAMP}.jar file --> <jar jarfile="${dist}/lib/MyProject-${DSTAMP}.jar" basedir="${build}"/> </target> <target name="clean" description="clean up" > <!-- Delete the ${build} and ${dist} directory trees --> <delete dir="${build}"/> <delete dir="${dist}"/> </target> </project>
这段代码做的事情是清除目录,创建目录,编译源文件,复制依赖至目标目录。这已经十分简单了,但是,为此你还是需要做一些配置:指定源码目录,指定编译字节码目录,指定目标目录,你还需要记住一些ant的配置命令,如delete, mkdir, javac, jar。这看起来没什么问题,至少目前是这样。
可能还有用shell脚本在做build这件事情,那么配置可能会比这个复杂一点(笔者不熟悉shell,如果有能将上述代码用shell重写一遍,笔者将不甚感激)。
现在说说Ant或shell/bat存在的问题,首先,有很多配置需要你填写,源码目录,字节码目录……,每一个项目,你都要重复这些劳动;第二,也是更重要的一点,你根本无法保证N个项目的ant配置(或shell)配置使用了相同的风格,后果是,每接受一个项目,开发者都要去学习这份脚本,以了解如何构建项目。如果第一个原因只是为了技术的简化的话,第二个原因更是软件工程的因素,我们不是一个人在开发项目,不是只开发一个项目,所以应该时刻谨记为了别人,为了将来。
现在看看使用Maven我们需要什么配置,就一个pom.xml文件:
<project> <modelVersion>4.0.0</modelVersion> <groupId>org.sonatype.mavenbook</groupId> <artifactId>my-project</artifactId> <version>1.0</version> </project>
不用惊讶,Maven不会变魔术,它能做到这么简单,是有条件的,条件就是你要遵守Maven约定。pom.xml所在的目录应为项目的根目录,假设该目录为${proj-dir},那么Maven有以下假设:
- ${proj-dir}/src/main/java —— 存放项目的.java文件。
- ${proj-dir}/src/main/resources —— 存放项目资源文件,如spring, hibernate配置文件。
- ${proj-dir}/src/test/jave —— 存放所有测试.java文件,如JUnit测试类。
- ${proj-dir}/src/test/resources —— 测试资源文件。
- ${proj-dir}/target —— 项目输出位置。
运行一条mvn clean package命令,Maven会帮你清除target目录,重新建一个空的,编译src/main/java类至target/classes,复制src/main/resources的文件至target/classes,编译src/test/java至target/test-classes,复制src/test/resources的文件至target/test-classes;然后运行所有测试;测试通过后,使用jar命令打包,存储于target目录。Maven做的事情一点也不少,只是都对用户隐蔽起来了,它只要求你遵循它的约定。
这么做有什么好处呢?第一,显而易见,配置大量减少了,随着项目变得越复杂,这种优势就越明显。第二,我这里要强调的是,对于软件工程来说,所有使用Maven的项目,对外都暴露统一的命令集。如mvn clean install。只要项目被正确配置好了,任何一个新人,输入一行Maven命令,就能将项目构建起来了,这大大减少了交流学习的时间。
这时可能会有人说,我不想遵守这种约定呢?我要把源码放在${proj-dir}/src/code目录下。首先,问自己三遍,你真的需要这样做么?如果仅仅是因为喜好,那么别耍个性,个性意味着牺牲通用性,意味着增加无谓的复杂度。以下是一个“个性”的例子:
<project> <modelVersion>4.0.0</modelVersion> <groupId>org.sonatype.mavenbook</groupId> <artifactId>my-project</artifactId> <version>1.0</version> <build> <sourceDirectory>src/java</sourceDirectory> <testSourceDirectory>src/test</testSourceDirectory> <outputDirectory>output/classes</outputDirectory> <testOutputDirectory>output/test-classes</testOutputDirectory> <directory>target/jar</directory> </build> </project>
很显然,Maven允许你自定义,比如这个例子中,Maven就被配置成从src/java目录寻找源码,编译class文件至output/classes,从src/test寻找测试源码,编译至output/test-classes目录,最后,打包jar文件至target/jar目录。Maven允许你这么做,但不推荐你这么做。因为一旦你使用这种自定义,习惯Maven约定的人一开始会觉得奇怪,src/main/java目录去哪里了?target下面怎么没有我要的jar文件?这些都造成了无谓的交流成本提高。只有一些特殊的情况,这些自定义手段能帮你解决实际的问题,比如你在处理遗留代码,你没办法改变源码目录结构,这个时候只有让Maven妥协。
下面总结一些Maven的默认值,也就是说,虽然你没做什么配置,但是你应该知道Maven假设它们成立,也就是所谓的“约定”:
目录src/main/java | java源码目录 |
目录src/main/resources | 资源文件目录 |
目录src/test/java | 测试java源码目录 |
目录src/test/resources | 测试资源文件目录 |
目录target | 打包输出目录 |
目录target/classes | 编译输出目录 |
目录target/test-classes | 测试编译输出目录 |
目录target/site | 项目site输出目录 |
目录src/main/webapp | web应用文件目录(当打包为war时),如WEB-INF/web.xml |
jar | 默认打包格式 |
*Test.java | Maven只会自动运行符合该命名规则的测试类 |
%user_home%/.m2 | Maven默认的本地仓库目录位置 |
中央仓库 | Maven默认使用远程中央仓库:http://repo1.maven.org/maven2 |
1.3 | Maven Compiler插件默认以1.3编译,因此需要额外配置支持1.5 |
其实基本上所有的约定,或者说默认配置,都可以在Maven的超级POM(super pom)中找到。由于所有的POM都继承了这个超级POM(类似于java中所有类都继承于Object),因此它的默认配置就被继承了。以Maven 2.0.9为例,你可以在%m2_home%/lib/下看到一个名为maven-2.0.9-uber.jar的文件,打开这个文件,可以找到org/apache/maven/project/pom-4.0.0.xml这个文件,这就是超级POM。
Maven提供了一套科学的默认配置,它要求你遵循这些配置约定,然后它就会帮你处理日常的事务compile, test, package等等。使用Maven的时候,你应该尽可能遵循它的配置约定,一方面可以简化配置,另一方面可建立起一种标准,减少交流学习成本。一旦你习惯了这种约定,你得到的回报是巨大的。反之,恣意的做自定义,想要Maven像Ant一样听你的话,那么你会讨厌Maven,Maven也会讨厌你。
评论
规约这个词不知道是谁创造出来的,听着都难受。现有的词汇可以表达的东西,就不要再发明创造了。
叫规约的也挺多的~~~~
发表评论
-
我的书《Maven实战》
2010-11-12 13:09 70147我本来已经决定停止更新该博客了,但是为了推广下我的新书《Mav ... -
m2eclipse 0.10.0发布
2010-02-22 17:34 8058本文译自 http://www.sonatyp ... -
按需构建多模块,玩转Maven反应堆
2010-01-07 19:57 29593在多模块Maven项目中,反应堆(Reactor)是一个包含了 ... -
Maven仓库的布局
2009-12-14 08:54 11970注:本文节选自我正在 ... -
Maven3初窥
2009-11-10 16:28 20782Maven3的开发已经完成大半,本周末将发布alpha-3(T ... -
Nexus 1.4.0 发布
2009-10-29 17:22 6236新完成的用户故事: [ NEXUS-463] - ... -
archtype:generate出错?
2009-10-12 00:10 8209我们常常会使用mvn archet ... -
你最常用的构建和发布管理工具是什么?
2009-09-13 15:03 13030最近Eclipse社区进行了一项调查,关注社区如何使用Ecli ... -
策划编写《Maven实战》——初步目录
2009-09-09 03:42 82552010-08-27更新 关注 ... -
Maven最佳实践:持续集成
2009-08-21 17:14 0test -
Maven最佳实践:集成web容器
2009-08-21 17:13 0test -
《Maven权威指南》完整发布,带官方PDF
2009-07-06 00:45 675772010/04/29更新 :我已 ... -
Nexus Indexer 2.0:增量下载
2009-05-14 16:33 10322原文:http://www.sonatype.com/peop ... -
Maven最佳实践:版本管理
2009-04-29 00:04 125038什么是版本管理 首先,这里说的版本管理(version ma ... -
Maven最佳实践:Maven仓库
2009-04-01 17:42 111054什么是Maven仓库 在不用M ... -
Maven中央仓库的中国镜像
2009-03-31 22:53 45945(2011-01-27更新,由于私人原因,该镜像已关闭,在此致 ... -
Nexus入门指南(图文)
2009-03-15 23:07 147706Nexus介绍 Nexus 是Maven仓 ... -
“第十七章 编写插件” 发布
2009-03-09 17:16 3920又是漫长的一章内容,但如同本书的任何一章一样,由于原作者都是M ... -
Maven最佳实践:管理依赖
2009-02-23 16:50 28367"If I have seen further it ... -
m2e:为Eclipse引入Maven(下)
2009-02-04 16:19 30366译自:http://www.sonatype.co ...
相关推荐
【MAVEN使用最佳实践】 Maven 是一个强大的项目管理和构建工具,它简化了Java应用程序的构建过程,通过一套约定优于配置的原则,使得项目构建、依赖管理和文档生成等工作变得标准化。以下是一些在使用Maven时可以...
**3.6 POM 最佳实践** - **3.6.1 依赖分组**:将相关的依赖放在一起,方便管理和查找。 - **3.6.2 多模块与继承** - **3.6.2.1 简单项目**:对于较小的项目,可以使用单一的 POM 文件来管理整个项目。 - **3.6....
- 组织结构:Maven遵循约定优于配置的原则,规定了标准的项目目录结构,如src/main/java、src/test/java等。 2. Maven生命周期: - Maven生命周期包括清理、默认和站点三个阶段,每个阶段包含多个阶段(如编译、...
在定义POM时,建议按照最佳实践来组织依赖和模块,比如通过分组依赖和使用多模块与继承的方式。 Maven的构建生命周期定义了项目的构建阶段和相关的生命周期目标。基本的生命周期包括clean、default和site三个阶段,...
Maven有许多最佳实践,如保持POM简洁、合理使用依赖范围、遵循约定的目录结构等,这些都可提高项目的可维护性和协作效率。 9. Maven的环境设置: Maven的配置文件settings.xml用于设置全局配置,如本地仓库位置、...
**Maven的最佳实践:** 1. **约定优于配置**:Maven遵循一套标准目录结构,如`src/main/java`存放源代码,`src/test/java`放测试代码。 2. **依赖管理**:避免硬编码版本号,尽可能利用传递性依赖,保持POM简洁。 3....
6. **Maven的最佳实践:** - 保持POM的简洁和模块化,避免过多的直接依赖。 - 使用统一的命名规则和目录结构。 - 定期更新依赖,确保项目的安全性。 - 利用Maven的多模块项目结构管理大型项目。 综上所述,...
### Maven 3.0 的最佳实践 - **遵循约定优于配置的原则**:使用Maven的标准目录结构,减少POM的配置。 - **合理管理依赖**:避免硬编码版本号,使用`<dependencyManagement>`元素统一管理版本。 - **使用父POM**:...
1. **遵循约定优于配置原则**: Maven有许多默认设置,如源码目录结构,遵循这些约定可以使项目更易维护。 2. **合理使用依赖管理**: 尽量减少对具体版本的硬编码,利用 `<dependencyManagement>` 元素管理依赖版本...
9. **最佳实践**:Maven 项目通常遵循一些最佳实践,如保持 POM 清晰简洁,合理使用模块化构建大型项目,以及定期清理本地仓库以避免依赖冲突。 综上所述,"maven-menu" 项目旨在提供一个更直观的方式来管理和浏览 ...
10. **最佳实践**:Maven推动了Java社区的一套构建和项目组织的最佳实践,如约定优于配置的原则,使得新项目可以快速启动,遵循统一的标准。 总的来说,Apache Maven 3.5.0是Java开发中不可或缺的工具,它极大地...
### Maven最佳实践 - **保持POM简洁**:避免在POM中添加不必要的配置,尽量利用Maven的默认设置。 - **使用父POM**:多个项目共享相同配置时,可以创建一个父POM来统一管理。 - **版本管理**:遵循 Semantic ...
1. **遵循约定优于配置原则**:Maven通过默认配置简化项目结构,如src/main/java存放源代码,src/test/java存放测试代码。 2. **合理使用依赖管理**:在父POM中定义公共依赖,子项目继承父POM,可以统一版本,减少...
3. **遵循约定优于配置**:利用Maven的默认配置,除非有特殊需求,否则尽量少修改。 总结起来,Maven3插件是Maven的核心功能之一,它们提供了丰富的功能来支持Java项目的构建和管理。通过合理地配置和使用插件,...
### Maven权威指南:深入解析与实战应用 #### 引言:Maven——自动化构建与项目管理的...通过本书的学习,开发者能够掌握Maven的核心理念和最佳实践,从而提升项目构建的效率和质量,使项目管理更加规范化和自动化。
### Maven实战最清楚版知识点概览 #### 1. Maven简介 ...- **8.5 约定优于配置**:Maven遵循“约定优于配置”的原则,如何利用这一点简化项目配置。 - **8.5 小结**:总结Maven的聚合与继承功能。
8. 最佳实践: - 避免在代码中硬编码路径,依赖于Maven的约定优于配置原则。 - 保持POM简洁明了,避免过度配置。 - 使用持续集成工具(如Jenkins)与Maven结合,实现自动化构建和测试。 通过这份详尽的Maven文档...
### Maven最佳实践 1. **遵循约定优于配置**:Maven有标准的目录结构,如src/main/java存放源码,src/test/java存放测试代码。 2. **合理设置POM**:确保POM文件简洁且准确,避免过度配置。 3. **使用依赖管理**...
#### 八、Maven最佳实践 为了更好地利用Maven,以下是一些推荐的最佳实践: 1. **遵循约定优于配置原则**: Maven内部已经定义了许多默认行为和约定,遵循这些约定可以减少不必要的配置工作。 2. **使用版本控制...