Month: January 2012

《Maven实战》笔记 5.2 – 继承

继承是为了实现“在父项目里声明,在各个子项目里使用”,比如项目的版本、项目的groupId、依赖等。 下面是项目module-base的pom.xml的片段 <!–module-base将继承module-root–> <parent> <groupId>mvn-module</groupId> <artifactId>module-root</artifactId> <version>1.0.0-SNAPSHOT</version> <relativePath>../pom.xml</relativePath> </parent> <!–这里不必再显式声明groupId和version。项目会自动从父项目中继承–> <artifactId>module-base</artifactId> ======================================== Super Pom   java中每个类都是java.lang.Object的子类,maven中每个项目的pom都是Super Pom的子pom. Super Pom是Maven内置的顶级Pom,Maven项目的默认目录结构就是在这里定义的。 ========================================= 对“依赖”的继承是最主要的用处之一。最佳实践是: 1. 父项目的pom.xml通过<dependencyManagement>声明所有会用到的dependency 2. 子项目的pom.xml通过<dependencies>声明所需的依赖。声明中不需要指明所依赖的构件的版本。 说明: 1.为什么要在父项目的pom中集中声明所有依赖? 因为这样可以保证,对同一个构件,所有子项目都会使用相同的版本。 2.为什么父项目中要用<dependencyManagement>而不直接用<dependencyies> ? 因为如果用后者,其中定义的dependency会被所有子项目继承,子项目在打包时会把这些构件打在自己的包中,即使这个子项目并不需要某些dependency.

《Maven实战》笔记 5.1 – aggregation

Maven项目大了,就要拆成多个小项目。这就是aggregation要干的事。 具体来说,就是要在各个小项目建好之后,再建一个专们用于聚合的项目。在这个项目的pom.xml里声明: <!–此类项目的打包方式必须为pom–> <packaging>pom</packaging> <!–在这里声明小项目–> <modules> <!–module-base, module-app是小项目的目录名–> <module>module-base</module> <module>module-app</module> </modules> 对这个项目执行一下"mvn package", Maven会自动构建小项目module-base 和 module-app 如果执行"mvn package -pl module-base",则Maven只构建module-base

《Maven实战》笔记 4.2 – maven命令与lifecycle&plugin的关系

mvn test   执行lifecycle "default"的phase "test". 由于phase "test"被绑定到surefire plugin的test goal, 因此surefire的test goal会被执行; 同时, phase "test"之前的所有的phase也会被执行。 mvn eclipse:eclipse   执行 eclipse plugin中的eclipse goal. "eclipse" plugin是哪个plugin? 如果没有特殊配置,Maven会去 http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-metadata.xml等默认metadata中寻找prefix=eclipse的配置

《Maven实战》笔记 4.1 – lifecycle和plugin的概念

a.Maven定义了标准的lifecycle,如 编译 -> 测试 -> 打包,每个步骤称作一个"phase"。phase有先后关系,执行一个phase前必须先执行前面所有的phase b.phase有名无实,只是一个虚的接口,本身并不做任何事情 c.plugin则做一些真正的事情,比如真正的编译、打包等。一个插件可以有多个功能点,每个功能点称作一个"goal" d.把phase 和 goal关联起来,就可以基于lifecycle进行构建了

《Maven 实战》笔记3.3 – internal repository与mirror

    internal repository是指在局域网内部搭建的repository,它跟central repository, jboss repository等的区别仅仅在于其URL是一个内部网址     mirror则相当于一个代理,它会拦截去指定的远程repository下载构件的请求,然后从自己这里找出构件回送给客户端。配置mirror的目的一般是出于网速考虑。     可以看出, internal repository和mirror是两码事。前者本身是一个repository,可以和其它repository一起提供服务,比如它可以用来提供公司内部的maven构件;而后者本身并不是repository,它只是远程repository的网络加速器。     不过,很多internal repository搭建工具往往也提供mirror服务,比如Nexus就可以让同一个URL,既用作internal repository,又使它成为所有repository的mirror

《Maven 实战》笔记3.2 – 让Repository区别对待snapshot版本和release版本

可以让Repository区别对待snapshot版本和release版本。也就是说,你可以只从jboss repository中下载release版本,并只从google repository中下载snapshot版本。      另外,考虑到本地Repository相当于远程Repository的缓存,应该设置一下缓存的更新频率,提供snapshot的repository更要设置(当然,也可以不显式设置,默认值是daily)         <repository> <!– … –> <releases> <!– 本repository不提供release版本下载 –> <enabled>false</enabled> </releases> <snapshots> <!– 本repository提供snapshot版本下载 –> <enabled>true</enabled> <!– 缓存每超过五分钟就要更新–> <updatePolicy>5</updatePolicy> </snapshots> <!– … –>   

《Maven 实战》笔记3.1 – Repository的概念及其在项目中的使用

1. Repository用来存放maven项目的构件,如pom, *.jar, *-source.jar等,它的布局像一个文件系统,有路径(目录)和文件 2. 使用Maven时,你会跟两类Repository打交道。    a. 存放在你本机那些的构件即组成“ 本地Repository”    b. 不在你本机的、存在服务器上的叫“ 远程Repository"。    当Maven需要构件时,首先会在本地Repository里找,找不到才去远程Repository中找。 3. Repository是相对于项目而言的,所以 你可以在项目级别配置远程的Repository,而且可以配多个。    一个Repository是一个 id + url + 其它信息的组合。id你可以随便取,url则是远程Repository的确切地址。 <project> <repositories> <repository> <id>jboss</id> <name>jboss</name> <url>https://repository.jboss.org/nexus/content/repositories/</url> … </repository> <repository> <id>google</id> <name>google</name> <url>http://google-maven-repository.googlecode.com/svn/repository/</url> … </repository> </repositories> … </project> 对此你可能有多种疑问: 问:项目里配了两个repository,那下载构件时,Maven去哪个repository呢? 答案:测试表明,Maven会先去定义在最前面的repository即"jboss"里去找; 如果找不到,再去"google"找 问:如果jboss和google里都找不到呢? 答:就去Maven默认的central repository里去找,它的id是"central", url是http://repo1.maven.org/maven2. 这个配置写死在maven的某个jar里面 问:如果我把上面的jboss repository换成"central"会怎么样? <project> …

《Maven 实战》笔记3.1 – Repository的概念及其在项目中的使用 Read More »

不建议把可以做在webapp里面的基础架构做到webapp外面

有很多基础服务,本来可以做在webapp里面的,但有人却选择把它做在webapp外面。 比如jboss提供的log4j服务,就是一个很讨厌的东西,很容易跟你应用里面的log4j冲突。 还有些服务,比如连接池服务,被强行做成了jndi,由容器来打理,这也很讨厌。 在我看来,把可以放里面的东西丢到外面有这样几个缺点:     1. 本可以由程序员完全控制的基础设施,现在要由运维人员来分担了。jndi就是一个例子。   2. 本可以由scm工具控制的东西,现在要经常手动来管理,这在版本管理方面往往产生问题。比如那些由jca写的、丢在jboss下面的东西,没办法用maven+svn直接管理了   3. 内外冗余造成的冲突问题。如果你的应用里使用了log4j,就可能跟jboss自带的log4j产生版本冲突和class loading冲突   4. 开发环境和其它环境的不一致问题。比如你开发用Tomcat,Tomcat不提供JNDI,所以你开发时不使用jndi那一套; 但正式环境用的又是jboss + jndi。结果就是你的代码或配置要支持两种东西,开发时不搞jndi,发布时要搞jndi

《Maven实战》笔记 2.4 - Optional依赖

Optional依赖:   假设App依赖了A, A“可选”地依赖了B,那App在打包时,会不会纳入B?   答案:不会。如果你的App里需要用到A中跟B相关的功能,那就需要把B用作App的直接依赖。  可选依赖不是什么好东西,它搞得你把传递依赖升级为直接依赖,很容易令人困惑,你的同事会问:为什么App要直接依赖B?   如果A对B有可选依赖,则应该把A拆成两个项目,其中A1依赖B,A2不依赖B,App再按需选择