Maven 使用指南

觉得在介绍Hibernate 之前有必要先介绍一下Maven的使用。下面摘自维基百科。

Apache Maven,是一个软件(特别是Java软件)项目管理自动构建工具,由Apache软件基金会所提供。基于项目对象模型(缩写:POM)概念,Maven利用一个中央信息片断能管理一个项目的构建、报告和文档等步骤。

简单的说Maven主要用来编译Java项目,使用XML来描述项目的组成部分:代码,资源及依赖关系。其主要目的是:

  • 简化编译(build)过程
  • 提供一个标准的编译系统
  • 通过高质量的项目信息
  • 为良好开发过程提供指南
  • 平稳过渡添加新功能

下面给出一个简单的Maven项目的POM(Project Object Model)文件,pom.xml 的作用类似makefile 或是 VS.Net 的 .prj .sln 文件

[html]  view plain copy print ?
  1. <project>  
  2.   <!-- model version is always 4.0.0 for Maven 2.x POMs -->  
  3.   <modelVersion>4.0.0</modelVersion>  
  4.   
  5.   <!-- project coordinates, i.e. a group of values which  
  6.        uniquely identify this project -->  
  7.   
  8.   <groupId>com.mycompany.app</groupId>  
  9.   <artifactId>my-app</artifactId>  
  10.   <version>1.0</version>  
  11.   
  12.   <!-- library dependencies -->  
  13.   
  14.   <dependencies>  
  15.     <dependency>  
  16.   
  17.       <!-- coordinates of the required library -->  
  18.   
  19.       <groupId>junit</groupId>  
  20.       <artifactId>junit</artifactId>  
  21.       <version>3.8.1</version>  
  22.   
  23.       <!-- this dependency is only used for running and compiling tests -->  
  24.   
  25.       <scope>test</scope>  
  26.   
  27.     </dependency>  
  28.   </dependencies>  
  29. </project>  

具体含义将在后面详述。

在学习Maven之前,请先下载Maven http://maven.apache.org/download.html
目前版本为 3.0.4.
为方便起见,请将下载后的Maven 的bin 目录添加到系统的Path 目录。这样在任何地方都可以键入mvn 命令行。
测试一下你安装好的Maven ,可以在命令行键入 mvn -version

注: Maven 需要Java支持,因此需要在系统中先安装JDK java.sun.com


在介绍第一个例子之前,先说一下为什么要使用Maven或是使用Maven有什么好处。

  • 管理多个.jar文件。在开发Java应用时常常需要使用大量的第三方开发包,这些开发包大多数是.jar 的形式提供,比如使用spring 框架,通常的用法是下载这些.jar 文件,然后添加到Java下面中。部署时也要一些打包这些.jar 文件。使用Maven,在POM 中描述所需引用(依赖的)的库,在编译,发布,部署时Maven会自动下载或本地寻找所需库文件。因此使用Maven通常需要有网络连接
  • 管理Java项目的依赖和版本,Java依赖的库有不同的版本,提供在POM文件指定所引用库的版本号,Maven自动帮助管理这些依赖关系及其版本。
  • 使用标准的项目结构,开发和测试人员可以使用标准的项目目录结构。
  • Maven定义了项目开发的几个标准步骤:编译,发布,单元测试及部署以帮助项目开发。

下载安装好Maven,我们就可以创建第一个项目。

在命令行下输入

mvn archetype:generate
第一次运行时,Maven会下载所需库文件,这需要一些时间

此时Maven 提示选择 archtype ,简单的讲archtype 指所需创建Java项目的类型,
1. 这里我们使用缺省的类型 217:
217: remote -> org.apache.maven.archetypes:maven-archetype-quickstart (An archetype which contains a sample Maven project
2. 使用缺省的新创建项目版本6: 1.1
3. 输入项目GroupId. 项目的GroupId 一般可以认为是项目的包名称,比如com.pstreets.mavendemo
4. 输入项目的artifactId,项目的artifactId 可以认为对于项目的主类名。比如HelloWorld.
5. 输入项目的version: 缺省为1.0-SNAPSHOT,标识项目打包到1.0-SNAPSHOT.jar
6. 输入package ,可以使用GroupId同样的包名称
Maven则创建项目HelloWorld,具有如下项目结构:

为方便起见,使用Eclipse将这个项目导入到Workspace, File->Import->Maven->Existing Maven Projects

Maven创建的文件几引用的库如下:

可以看到Mavan创建了两个目录main和test 分别对应项目的代码和测试代码。

打开项目的pom.xml

[html]  view plain copy print ?
  1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  2.   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  
  3.   <modelVersion>4.0.0</modelVersion>  
  4.   
  5.   <groupId>com.pstreets.mavendemo</groupId>  
  6.   <artifactId>HelloWorld</artifactId>  
  7.   <version>1.0-SNAPSHOT</version>  
  8.   <packaging>jar</packaging>  
  9.   
  10.   <name>HelloWorld</name>  
  11.   <url>http://maven.apache.org</url>  
  12.   
  13.   <properties>  
  14.     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>  
  15.   </properties>  
  16.   
  17.   <dependencies>  
  18.     <dependency>  
  19.       <groupId>junit</groupId>  
  20.       <artifactId>junit</artifactId>  
  21.       <version>3.8.1</version>  
  22.       <scope>test</scope>  
  23.     </dependency>  
  24.   </dependencies>  
  25. </project>  

可以看到刚才输入的,和,实际上Maven使用这三个值来唯一指定一个项目。引用一个库文件也是通过这三个值来确定所引用的库及其版本好,比如本例引用最新的junit 库版本为3.8.1. 此时假定junit还需引用其它库,Maven自动管理而无需在pom文件中指定。

创建好项目中,可以打开main 中的App.java 和 test目录中的AppTest.java 看一下:

App.java

[java]  view plain copy print ?
  1. package com.pstreets.mavendemo;  
  2.   
  3. /** 
  4.  * Hello world! 
  5.  * 
  6.  */  
  7. public class App   
  8. {  
  9.     public static void main( String[] args )  
  10.     {  
  11.         System.out.println( "Hello World!" );  
  12.     }  
  13. }  
AppTest.java

[java]  view plain copy print ?
  1. package com.pstreets.mavendemo;  
  2.   
  3. import junit.framework.Test;  
  4. import junit.framework.TestCase;  
  5. import junit.framework.TestSuite;  
  6.   
  7. /** 
  8.  * Unit test for simple App. 
  9.  */  
  10. public class AppTest   
  11.     extends TestCase  
  12. {  
  13.     /** 
  14.      * Create the test case 
  15.      * 
  16.      * @param testName name of the test case 
  17.      */  
  18.     public AppTest( String testName )  
  19.     {  
  20.         super( testName );  
  21.     }  
  22.   
  23.     /** 
  24.      * @return the suite of tests being tested 
  25.      */  
  26.     public static Test suite()  
  27.     {  
  28.         return new TestSuite( AppTest.class );  
  29.     }  
  30.   
  31.     /** 
  32.      * Rigourous Test <img src="http://www.imobilebbs.com/wordpress/wp-includes/images/smilies/icon_smile.gif" alt=":-)" class="wp-smiley">  
  33.      */  
  34.     public void testApp()  
  35.     {  
  36.         assertTrue( true );  
  37.     }  
  38. }  

这样项目就创建好了,既可以在命令行中使用mvn 来compile (编译) ,test(单元测试), package(打包)
也可以通过Eclipse 来编译,测试项目

比如在命令行中输入mvn package 会创建target 目录,其中生成打包文件 HelloWorld-1.0-SNAPSHOT.jar ,可以通过命令

java -cp .\HelloWorld-1.0-SNAPSHOT.jar com.pstreets.mavendemo.App

则显示 Hello World!

其实 mvn package 会调用compile ,test 等步骤,后面将详细描述。

前面例子创建了一个HelloWorld应用,所做的工作就是通过命令行输入mvn archetype:generate,然后给出GroupId, artifactId,及Version等信息,Maven就创建了一个新的项目,包括应用本身和Junit单元测试代码框架。
下面给出了Maven的基本工作过程。

Maven 是根据存储在Maven repository 的信息来决定其操作,存放在Maven Repository的信息包括两个部分:

  • Archtype Info相当于项目的模板,Maven根据archtype 来构造新创建项目的文件结构,比如前面使用的是缺省的generate 创建一个Java应用
  • Dependency Info 存放了不同Jar(库)之间的相互依赖(引用关系)

当在命令行调用maven 命令时,maven 通过访问Maven repository 中的信息创建新项目的目录结构(directory structure),下载所依赖的库文件(jar),HelloWorld 只依赖Junit. 并将项目信息写到pom.xml 文件中。你可以通过修改pom.xml 来添加其它引用的库文件。Maven则自动下载所需库文件。

有了前面的三篇文章,就可以开始使用Eclipse来创建Maven 项目开发Java应用了。前面用到了

mvn compile

mvn test

mvn package

等命令。

Maven定义了编译打包项目生命周期活动的标准阶段,compile, test ,package 是创建Build生命周期活动的一个阶段。下图定义了Maven Build生命周期的主要阶段。

  • generate-sources: 通常是通过插件支持创建额外的源代码。
  • compile: 编译项目应用代码
  • test-compile: 编译项目单元测试代码
  • test: 运行项目单元测试(一般为Junit 测试)
  • package: 打包项目可以执行代码(以Jar/War/Ear形式)
  • integration-test: 如有需要处理及部署应用以便执行系统集成测试。
  • install: 将应用打包发布到本地Maven 软件包以便其它Maven引用。(注意Install不是指安装Java应用)
  • deploy: 发布到远程Maven软件包以便其他Maven项目下载引用。

每个Maven阶段命令最终是通过Maven的插件来运行的。没个被调用的阶段命令自动调用其生命周期前面的阶段命令,比如mvn package 会依次运行compile , test 阶段命令。

运行Maven阶段命令,是进入到Maven项目包含pom.xml 的目录,

然后运行 mvn [command]

例如 对Hello World  项目运行 mvn package ,命令依次调用 compile, test 及package 本身。

 

如果使用Eclipse IDE,可以通过菜单来执行Maven命令:

 

从Maven2 开始,Maven可以自动管理Java应用所引用的开发包(Jar包),原文为transitive dependency (可传递的依赖管理),也就是说Java应用只需要定义其直接引用的Jar包依赖,而无需定义Java应用所引用的所有Jar 依赖。Maven 2可以自动添加Java应用直接引用库所依赖的其它Jar包。

这里我们可以下载hibernate 的一个示例,可以从http://www.hibernate.org/下载,也可以从本站下载.

使用Eclipse –>Import-> Existing Maven Project 打开这个Maven Project。

打开hibernate-tutorials/pom.xml 其dependency 部分定义如下:

[html]  view plain copy print ?
  1. <dependencies>  
  2.     <dependency>  
  3.       <groupId>org.hibernate</groupId>  
  4.       <artifactId>hibernate-core</artifactId>  
  5.       <version>4.1.6.Final</version>  
  6.       <scope>compile</scope>  
  7.     </dependency>  
  8.     <dependency>  
  9.       <groupId>org.slf4j</groupId>  
  10.       <artifactId>slf4j-simple</artifactId>  
  11.       <version>1.6.1</version>  
  12.       <scope>compile</scope>  
  13.     </dependency>  
  14.     <dependency>  
  15.       <groupId>junit</groupId>  
  16.       <artifactId>junit</artifactId>  
  17.       <version>4.10</version>  
  18.       <scope>compile</scope>  
  19.     </dependency>  
  20.     <dependency>  
  21.       <groupId>com.h2database</groupId>  
  22.       <artifactId>h2</artifactId>  
  23.       <version>1.2.145</version>  
  24.       <scope>compile</scope>  
  25.     </dependency>  
  26.   </dependencies>  
  27.    

而实际引用到的所有Jar包的层次如下:

可以看到hibernate-core 又引用了不少其它Jar,这些Maven都可以自动计算出并下载所需依赖。而无需再pom.xml 中一一列出。

在定义dependency时还可以指定其引用的scope,比如有些引用可能只是用在单元测试而不会添加到最终发布的jar包中。Maven支持下面几种Scope:

  • compile: 缺省Scope,应用到Maven所有阶段。
  • provided: 只在编译代码时需要,而无需发布到最终Jar包中。
  • runtime: 只在运行时需要,比如JDBC驱动。
  • test: 只在编译和运行单元测试时需要,比如Juint测试。

Maven 使用指南(4): Maven Build 的阶段时介绍过Maven的阶段命令最终是通过Maven的插件来运行的。

Maven采用插件方式的好处是灵活(可以配置),可以扩展(可以开发插件以满足项目Build的需求,比如编译打包项目后,可以通过插件将应用部署到远程服务器等)。

Maven预先定义了很多插件,可以参见http://maven.apache.org/plugins/ ,如果需要另外开发插件,可以参见http://maven.apache.org/plugin-developers/index.html

在Maven中使用插件是通过在pom.xml 中使用plugins 定义,比如 修改缺省的compiler 插件使用Java编译的版本。

[html]  view plain copy print ?
  1. <build>  
  2.   <plugins>  
  3.     <plugin>  
  4.       <groupId>org.apache.maven.plugins</groupId>  
  5.       <artifactId>maven-compiler-plugin</artifactId>  
  6.       <version>2.0.2</version>  
  7.       <configuration>  
  8.         <source>1.5</source>  
  9.         <target>1.5</target>  
  10.       </configuration>  
  11.     </plugin>  
  12.   </plugins>  
  13. </build>  

可以看出使用plugin 的方法和定义依赖的非常类似,其中configuration部分用来配置插件参数。具体可以参见插件文档

Mavne的插件分为两类:

  • Build plugins  在Build生命周期中执行,必须定义在<build/>元素下.
  • Reporting plugins 在生产site阶段运行,定义在<reporting/> 元素。

和定义依赖一样,使用插件也必须定义groupIdartifactId 和version。

使用Maven 打包资源文件无需修改pom.xml ,对于一般的Maven项目,Maven 通过标准的文件目录结构来搜寻资源文件,自动将其打包到最终的jar, war包中。

Maven将所有存放在目录${basedir}/src/main/resources 下的所有文件及其目录原封不动的大包到Jar包中,

例如,修改Maven 使用指南(2): 第一个例子Hello World ,在main 目录下创建一个resources 目录,然后创建一个META-INF子目录,在META-INF目录下添加一个application.resources 文件。

然后再命令行使用mvn package 在target 目录下生成HelloWorld-1.0-SNAPSHOT.jar,解压这个文件,可以看到application.resources 文件中目录META-INF目录下:

可以看到META-INF 目录下还有其它一些文件,是有Maven生成的,对于MANIFEST.MF你可以使用自定义的MANIFEST.MF,如果没提供,Maven自动生成一个。

在test 目录中也可以添加resources 目录来使用资源。然后使用如下类似代码来访问资源

[java]  view plain copy print ?
  1. // Retrieve resource  
  2. InputStream is = getClass().getResourceAsStream( "/application.properties" );  
  3.   
  4. // Do something with the resource  

可以使用Maven来管理多个项目,首先是添加一个父pom.xml 文件,在所需管理项目的上一级,还是以hibernate tutorial 项目为例:

其中父pom.xml 的packaging 必须为 pom 类型

[html]  view plain copy print ?
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0   
  3.   
  4. http://maven.apache.org/xsd/maven-4.0.0.xsd"  
  5.   
  6.     xmlns="http://maven.apache.org/POM/4.0.0"  
  7.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">  
  8.   <modelVersion>4.0.0</modelVersion>  
  9.   <groupId>org.hibernate.tutorials</groupId>  
  10.   <artifactId>hibernate-tutorials</artifactId>  
  11.   <version>4.1.6.Final</version>  
  12.   <packaging>pom</packaging>  
  13.   <name>Hibernate Getting Started Guide Tutorials</name>  
  14.   <description0>  
  15.      Aggregator for the Hibernate tutorials presented in the Getting Started Guide  
  16.  </description>  
  17.   <modules>  
  18.     <module>basic</module>  
  19.     <module>annotations</module>  
  20.     <module>entitymanager</module>  
  21.     <module>envers</module>  
  22.   </modules>  
  23.   <properties>  
  24.     <maven.deploy.skip>true</maven.deploy.skip>  
  25.   </properties>  
  26.   <dependencies>  
  27.     <dependency>  
  28.       <groupId>org.hibernate</groupId>  
  29.       <artifactId>hibernate-core</artifactId>  
  30.       <version>4.1.6.Final</version>  
  31.       <scope>compile</scope>  
  32.     </dependency>  
  33.     <dependency>  
  34.       <groupId>org.slf4j</groupId>  
  35.       <artifactId>slf4j-simple</artifactId>  
  36.       <version>1.6.1</version>  
  37.       <scope>compile</scope>  
  38.     </dependency>  
  39.     <dependency>  
  40.       <groupId>junit</groupId>  
  41.       <artifactId>junit</artifactId>  
  42.       <version>4.10</version>  
  43.       <scope>compile</scope>  
  44.     </dependency>  
  45.     <dependency>  
  46.       <groupId>com.h2database</groupId>  
  47.       <artifactId>h2</artifactId>  
  48.       <version>1.2.145</version>  
  49.       <scope>compile</scope>  
  50.     </dependency>  
  51.   </dependencies>  
  52.   <repositories>  
  53.     <repository>  
  54.       <snapshots>  
  55.         <enabled>false</enabled>  
  56.       </snapshots>  
  57.       <id>central</id>  
  58.       <name>Maven Repository Switchboard</name>  
  59.       <url>http://repo1.maven.org/maven2</url>  
  60.     </repository>  
  61.   </repositories>  
  62.   <pluginRepositories>  
  63.     <pluginRepository>  
  64.       <releases>  
  65.         <updatePolicy>never</updatePolicy>  
  66.       </releases>  
  67.       <snapshots>  
  68.         <enabled>false</enabled>  
  69.       </snapshots>  
  70.       <id>central</id>  
  71.       <name>Maven Plugin Repository</name>  
  72.       <url>http://repo1.maven.org/maven2</url>  
  73.     </pluginRepository>  
  74.   </pluginRepositories>  
  75.   <build>  
  76.     <plugins>  
  77.        ....  
  78.     </plugins>  
  79.   </build>  
  80.   <reporting>  
  81.     ...  
  82.   </reporting>  
  83. </project>  

此时可以把需管理的项目的共用的dependencies ,plugin 移动到这个父pom.xml ,然后使用modules 添加到父pom.xml 中。

修改子项目的pom.xml ,添加一个parent 元素。比如 basic 项目的 pom.xml

[html]  view plain copy print ?
  1. project xmlns="http://maven.apache.org/POM/4.0.0"   
  2.    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
  3.    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0   
  4.   
  5. http://maven.apache.org/xsd/maven-4.0.0.xsd">  
  6.   
  7.     <modelVersion>4.0.0</modelVersion>  
  8.   
  9.     <parent>  
  10.         <groupId>org.hibernate.tutorials</groupId>  
  11.         <artifactId>hibernate-tutorials</artifactId>  
  12.         <version>4.1.6.Final</version>  
  13.         <relativePath>../pom.xml</relativePath>  
  14.     </parent>  
  15.   
  16.     <artifactId>hibernate-tutorial-hbm</artifactId>  
  17.     <name>Hibernate hbm.xml Tutorial</name>  
  18.     <description>  
  19.        Hibernate tutorial illustrating the use of native APIs and hbm.xml for mapping metadata  
  20.     </description>  
  21.   
  22.     <properties>  
  23.         <!-- Skip artifact deployment -->  
  24.         <maven.deploy.skip>true</maven.deploy.skip>  
  25.     </properties>  
  26.   
  27. </project>  

如果使用eclipse IDE ,就更简单了,直接通过modules 来管理模块:

本文是Maven系列教程最后一篇。


转载来自http://blog.youkuaiyun.com/mapdigit/article/category/1238213
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值