通过Maven构建Java项目

本指南将指导你利用Maven构建一个简单的Java项目。

你所构建

你将使用Maven来构建一个应用程序,它将提供一天中的时间。

你所需要

  • 大约15min
  • 一个你喜欢的代码编译器
  • JDK6或者更高版本

如何完成本指南

想大多数的Spring入门指南一样,你可以从头开始然后完成每一步,或者你可以绕过已经熟悉的基本设置步骤。无论哪种方法,你都会得到工作代码。

想从头开始?请移步设置项目

跳过了基础设置?继续看以下内容:

  • 下载并解压本指南的源储存库,或者通过Git clone本指南:git clone https://github.com/spring-guides/gs-maven.git
  • cd 进入gs-maven/initial
  • 跳转到初始化

当你完成之后,你可以根据gs-maven/complete中的代码检验结果。

设置项目

首先你需要通过Maven来构建一个Java项目,只需要注意Maven,至于这个项目可以尽量的简单

创建目录结构
在你选中的项目目录中,创建以下子目录结构;例如,在Unix/Linux系统中使用命令 mkdir -p src/main/java/hello

└── src
    └── main
        └── java
            └── hello

src/main/java/hello这个目录中,你可以创建任何你想要的Java class文件。为了保持与本指南其余部分的一致,创建以下两个class文件:HelloWorld.javaGreeter.java

src/main/java/hello/HelloWorld.java

package hello;

public class HelloWorld {
    public static void main(String[] args) {
        Greeter greeter = new Greeter();
        System.out.println(greeter.sayHello());
    }
}

src/main/java/hello/Greeter.java

package hello;

public class Greeter {
    public String sayHello() {
        return "Hello world!";
    }
}

至此你已经有了一个可以用Maven来构造的项目,接下来就是安装Maven。

你可以通过http://maven.apache.org/download.cgi下载作为压缩文件的Maven。只需要二进制文件,所以只需要找到apache-maven-{version}-bin.zipapache-maven-{version}-bin.tar.gz的连接即可。

下载压缩文件并解压它,之后将它bin文件夹的路径添加到环境变量path中。

若想测试Maven的安装情况,在命令行执行以下命令:
mvn - v

如果一切正常,你可以看到一些关于Maven的安装信息,例如下面所展示的内容(可能有些轻微的区别):

Apache Maven 3.0.5 (r01de14724cdef164cd33c7c8c2fe155faf9602da; 2013-02-19 07:51:28-0600)
Maven home: /usr/share/maven
Java version: 1.7.0_09, vendor: Oracle Corporation
Java home: /Library/Java/JavaVirtualMachines/jdk1.7.0_09.jdk/Contents/Home/jre
Default locale: en_US, platform encoding: UTF-8
OS name: "mac os x", version: "10.8.3", arch: "x86_64", family: "mac"

恭喜你!Maven已经成功安装啦!

定义一个简单的Maven构造

Maven已经安装,现在你需要做的就是创建一个Maven项目定义。Maven项目有一个名叫pom.xml的XML文件,它将定义整个项目。除此之外,它还定义了项目的名称、版本和对于外部库的依赖关系。

在项目的根目录中创建一个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/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.springframework</groupId>
    <artifactId>gs-maven</artifactId>
    <packaging>jar</packaging>
    <version>0.1.0</version>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>2.1</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <transformers>
                                <transformer
                                    implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                    <mainClass>hello.HelloWorld</mainClass>
                                </transformer>
                            </transformers>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

除了可选元素<packaging>,以上就是一个Java项目需要的最简单的pom.xml文件。它包括以下项目配置的细节:

  • <modelVersion>,POM版本(通常是4.0.0);
  • <gropId>,本项目属于哪一个项目组,通常用它的反转域名作为名称;
  • <artifactId>,给与项目artifact的名称(例如,那些名字中包含JAR和WAR的文件)
  • <version>,正在构造的项目的版本
  • <packaging>,项目应该以哪种形式被打包,默认用“jar”打包JAR文件,用“war”打包JAR文件。

当谈到选择一个版本控制方案,Spring推荐使用semantic versioning

在这一点上,你已经定义了一个最小但是又有能力的Maven项目!

构建Java代码

Maven现在已经准备好构建你的项目了!你可以使用Maven执行几个构建生命周期目标,其中包括编译你的项目代码,创建库包(如JAR文件 ),并将库安装到本地Maven依赖关系库中。
若想尝试构建,请在命令行输入以下命令:
mav compile
它会运行Maven,通知Maven运行编译这个功能。当编译完成,你可以在target/classes目录中找到那个被编译的.class文件
由于你不可能直接分发或使用.class文件,你可能跟你想运行包命令:
mvn package
打包命令将编译你的Java代码,运行所有的测试用例,然后把代码导报成一个JAR文件,放在target文件夹中。JAR文件的命名基于项目的<artifactId><version>。举个栗子,在前面提到的最基本的pom.xml,它的JAR文件将被命名为gs-maven-0.1.0.jar

如果你改变了<packaging>中的值,从“jar”变成“war”,那么结果将是target中的文件是WAR,而不是JAR文件。

为了快速访问项目的依赖,Maven在本机维护了一个依赖关系库(通常是在.m2/repository这个目录下)。如果你想安装项目的JAR文件到本地库,只需要执行install命令
mvn install
这个命令将编译、测试和打包你项目的代码,然后把它拷贝到依赖关系库中,为其他项目
同一个依赖参考。
说了这么久的依赖,是时候在Maven构建中声明依赖关系了。

声明依赖

Hello World这个简单的实示例完全的独立的,并不需要依赖其他的外部库。但是对于大多数应用来说,都需要依赖外部库来处理一些常见且复杂的功能。
举个栗子,假设除了say“Hello World!”,你还想让这个应用打印出当前的日期和时间,虽然你可以使用Java库中的日期和时间工具,但如果使用Joda Time库来操作,会变得非常有趣。
首先,修改你的Hello World.java文件,就像以下这样:
src/main/java/hello/HelloWorld.java

package hello;

import org.joda.time.LocalTime;

public class HelloWorld {
    public static void main(String[] args) {
        LocalTime currentTime = new LocalTime();
        System.out.println("The current local time is: " + currentTime);
        Greeter greeter = new Greeter();
        System.out.println(greeter.sayHello());
    }
}

这里的HelloWorld用了Joda Time的LocalTime类来获取当前的打印的时间。
如果你现在运行mvn compile来构建项目,这个构建必将失败,其原因是你还没有将Joda Time声明成一个编译依赖。你可以通过增加以下的代码到pom.xml文件(增加到<project>这个元素里)来修复这个问题:

<dependencies>
        <dependency>
            <groupId>joda-time</groupId>
            <artifactId>joda-time</artifactId>
            <version>2.9.2</version>
        </dependency>
</dependencies>

这个XMl快声明了项目的依赖关系列表,具体来说,它为Joda Time库声明了一个依赖关系。在<dependency>元素中,依赖坐标由三个子元素定义:

  • <groupId> - 这个依赖关系属于什么组织
  • <artifactId> - 被要求的库
  • <version> - 这个库被要求的具体版本

默认的,所有的依赖关系都作为编译依赖关系,意思是,他们将在编译时候被利用到(如果你正在构造一个WAR文件,包括在WAR的/WEB-INF/libs文件夹中)。另外,你可以指定<scope>元素来指定以下范围之一:

  • <provided> - 编译项目代码所需要的依赖关系,但运行时将由运行代码容器提供(例如Java Servlet API)
  • <test> - 依赖关系在编译和运行测试的时候将被用到,但是在构建或运行项目的运行代码不是必需的

那么现在,如果你再次运行mvn compile或者mvn package,Maven将从Maven中心库中解析Joda Time依赖,然后就构建成功了。

写一个测试

首先添加一个JUnit依赖到你的pom.xml文件中,作用域为test

<dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
</dependency>

接下来创建一个测试用例像以下所示:
src/test/java/hello/GreeterTest.java

package hello;

import static org.hamcrest.CoreMatchers.containsString;
import static org.junit.Assert.*;

import org.junit.Test;

public class GreeterTest {

    private Greeter greeter = new Greeter();

    @Test
    public void greeterSaysHello() {
        assertThat(greeter.sayHello(), containsString("Hello"));
    }

}

Maven使用一个名叫“surefire”的插件来运行单元测试,此插件默认配置是编译并运行在src/test/java中名称与*Test匹配的类。你可以通过以下的命令行来运行这些测试
mvn test
或者用mvn install,就像我们在上面已经提到过的那样(有一个生命周期定义,“test”被包括在“install”阶段)。
这里有一个完整的pom.xml文件:
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/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.springframework</groupId>
    <artifactId>gs-maven</artifactId>
    <packaging>jar</packaging>
    <version>0.1.0</version>

    <dependencies>
        <!-- tag::joda[] -->
        <dependency>
            <groupId>joda-time</groupId>
            <artifactId>joda-time</artifactId>
            <version>2.9.2</version>
        </dependency>
        <!-- end::joda[] -->
        <!-- tag::junit[] -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <!-- end::junit[] -->
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>2.1</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <transformers>
                                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                    <mainClass>hello.HelloWorld</mainClass>
                                </transformer>
                            </transformers>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

这个完整的pom.xml文件使用Maven Shade Plugin来简化JAR文件的可执行性。本指南专注于开始使用Maven,而不是使用这个插件。

摘要

恭喜你!你已经创造了一个简单的有用的通过Maven定义并构造的Java项目

扩展浏览

下面的这个指南或许能更好的帮助到你

想要写一个全新的入门指南或者为现有的入门指南做贡献么?点击贡献指南

所有的指南都将发布ASLv2许可证的代码、Attribution还有为写作颁发的NoDerivatives creative commons license

原文地址:Building Java Projects with Maven

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容