前言

不知道你是否以前经常遇到把一个project的相关依赖配置好,想启动看看效果,但却遇到一个ClassNotFoundException的失败?
不知道你是不是有不知道把src文件一test文件放哪的选择困难,或者不知道resources文件放哪的纠结?
Maven,就是它。有了它,java项目管理不再是问题。

安装

前期准备:安装JDK环境。

Ubuntu jdk7:
sudo apt-get install openjdk-7-jdk -y

Windows请到Oracle JDK下载安装,现在应该都会自动配置环境变量,如果没配置成功,请自行搜索配置。

安装完成后,在命令行运行:
java -version
如果显示了java的版本信息,表示安装成功。

安装Maven

在ubuntu下面直接执行:
sudo apt-get install maven -y
就能直接安装并配置好相关的环境变量。

windows下需要到Maven下载页面下载maven开发包,比如解压到D:/maven下,设置环境变量:
M2_HOME = D:/maven

运行mvn -v如果看到版本信息,说明安装配置成功。

maven仓库默认在用户目录下的.m2目录下,linux可以用cd ~/.m2快速切换到该目录下,windows用户请到Users\user.m2目录下查看。
maven项目查找依赖的时候首先会在本地仓库查找,如果找不到,就会到远程仓库查找并同步到本地,下一次再用的时候就能快速定位到本地仓库的资源。

创建Maven项目

快速创建一个webapp
mvn archetype:generate -DinteractiveMode=false -DarchetypeArtifactId=maven-archetype-webapp -DgroupId=org.codelogger -DartifactId=web-demo -Dversion=1.0.0-SNAPSHOT

也可以通过交互式创建mvn archetype:generate

当然,你也可以用IDE来创建Maven项目,Eclipse如下:
File > New > Other > Maven Project, 如果按原型创建,就按Next,如果要自定义创建,就勾上Create a simple project。
自定义创建里面可以比较详细的定义项目属性,尤其是parennt project非常有用,我自己就创建了一个Codelogger Parent Pom, 里面定义了常用的工具集(Codelogger Utils,Guava,Common-lang Utils),及常用的项目版本整合(Spring,Hibernate,etc),及测试环境。

关于pom.xml

下面是一个pom.xml的示例,有点长,可以略过这里直接住下看:

<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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.codelogger</groupId>
        <artifactId>parent-pom</artifactId>
        <version>1.0.0</version>
    </parent>

    <artifactId>web-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>

    <name>Codelogger Web Project Demo</name>
    <description>Codelogger webapp demo, build with Spring MVC, Spring JPA and Hibernate</description>

    <url>https://github.com/defei/codelogger-core</url>
    <licenses>
        <license>
            <name>The Apache Software License, Version 2.0</name>
            <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
        </license>
    </licenses>

    <developers>
        <developer>
            <name>Deng Defei</name>
            <email>dengdefei@gmail.com</email>
        </developer>
    </developers>

    <scm>
        <connection>scm:git:git@github.com:defei/web-demo.git</connection>
        <developerConnection>scm:git:git@github.com:defei/web-demo.git</developerConnection>
        <url>git@github.com:defei/codelogger-core.git</url>
    </scm>

    <properties>
        <web.version>1.0.0</web.version>
        <maven-compiler-plugin.version>3.1</maven-compiler-plugin.version>
        <java.version>1.7</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.codelogger</groupId>
            <artifactId>web</artifactId>
            <version>${web.version}</version>
        </dependency>
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
        </dependency>
    </dependencies>

    <profiles>
        <profile>
            <id>dev-mysql</id>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
            <properties>
                <profileName>dev-mysql</profileName>
                <logPath>~/Desktop</logPath>
            </properties>
        </profile>
        <profile>
            <id>production</id>
            <properties>
                <profileName>production</profileName>
                <logFile>/var/www/codelogger.org/web-demo/logs</logFile>
            </properties>
        </profile>
    </profiles>

    <build>
        <resources>
            <resource>
                <directory>docs/commons</directory>
                <filtering>true</filtering>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
            </resource>
            <resource>
                <directory>docs/profiles/${profileName}</directory>
                <filtering>true</filtering>
            </resource>
        </resources>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>${maven-compiler-plugin.version}</version>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
Maven项目的唯一性

pom里面的下面三个属性非常重要:

  • 项目 groupId(组织名:隶属于哪个公司或组织,如org.codelogger
  • 项目 artifactId(构件名):该组织下,项目的唯一标识符
  • 项目 version(版本号):原则做到语义化版本最好

【groupId】,【artifactId】,【version】可以精确定位到一项目的指定版本,所以具有唯一性,你在Maven中央库中就能通过这三个属性找到对应的项目,这样才能准确的管理好项目依赖。

小提示:version可以指定为RELEASED,这样项目就会去找最新的released的版本,好处是可以用到新特性,缺点是可能造成项目不稳定。

Maven的继承关系

pom是可以继承的,所以我们可以在Parent Pom里面做依赖管理等操作,然后在子项目里面,只需要定义需要哪些依赖,然后依赖版本就会自动从父级继承下来。

比如上面展示的:

<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
</dependency>

没有指定version,但一样能用,就是因为我们在Parent Pom<dependencyManagement>里面已经定义过版本信息了。

其它的,比如properties, plugins, profile, dependency, resources等,都是可继承的。

项目说明信息
  • name:项目的名称
  • description:项目的具体描述
  • url:项目页面Web地址
  • licenses:版权信息
  • developers:开发者
  • scm:软件配置管理,如git,cvs信息
properties
<properties>
    <web.version>1.0.0</web.version>
    <java.version>1.7</java.version>
</properties>

properties定义了一系列的property,使用的时候,用${property.key}就能输出里面的值。

除了定义公共的<properties>外,我们还可以在<profiles>里面的<profile>里定义私有的properties,如下:

<profiles>
    <profile>
        <id>dev-mysql</id>
        <properties>
            <profileName>dev-mysql</profileName>
            <logPath>~/Desktop</logPath>
        </properties>
    </profile>
</profiles>

profile里面的properties权限比公共的大,也就是说如果名称都是一样的,会复写掉公共properties里面的数据,这样我们就可以做到非常灵活的定制了。

dependencies

dependencies定义了该项目的依赖关系,如果你需要引入一个依赖,只需要在dependencies里面定义一个dependency,并指定正确的groupId,artifactId以及version,就能自动载入这个依赖,如下:

<dependencies>
    <dependency>
        <groupId>org.codelogger</groupId>
        <artifactId>web</artifactId>
        <version>${web.version}</version>
    </dependency>
</dependencies>

同properties一样,我们也可以在profile里面自定义dependencies,权重关系也是以profile的重,并且是profile隔离的。

profiles

profiles我们可以理解为pipeline,项目在运行的时候,只能选择一个profile,所以我们可以根据不同的profile做出不同的响应,比如dev这个profile,我们的数据库可以采用dbunit数据库,production的可以采用mysql数据库。
profile和<build><resources>一起使用的话,就可以做到根据不同的profile,载入不同的配置文件。

maven切换profile的命令是
maven -P profileId

build

build定义了maven在管理项目的时候的配置,下面主要介绍resources和plugins,示例如下:

<build>
    <resources>
        <resource>
            <directory>docs/commons</directory>
            <filtering>true</filtering>
        </resource>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
        </resource>
        <resource>
            <directory>docs/profiles/${profileName}</directory>
            <filtering>true</filtering>
        </resource>
    </resources>
    <plugins>
        <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>${maven-compiler-plugin.version}</version>
            <configuration>
                <source>${java.version}</source>
                <target>${java.version}</target>
            </configuration>
        </plugin>
    </plugins>
</build>

resources定义了该项目的classPath,我们可以添加多个resource目录,并且当把filtering设置为true的时候,该目录下所有的文件,都会被扫描,如果有${property.key},并且在properties里面有匹配的数据,则${property.key}会被替换为其对应的值,这样就能在pom.xml里对对项目乃至对profile做特定配置了。

plugins定义了build的时候会用到哪些插件,比如上面,我们用到的maven-compiler-plugin,在项目用mvn compile的时候,就会按我们指定的java版本编译。

Maven命令

maven的命令有两种响应方式:

  1. mvn <插件>:<目标> [参数]
  2. mvn <行为>

第二种方式是我们使用最频繁的,例如:

  • mvn clean:清空输出目录(即 target 目录)
  • mvn compile:编译源代码
  • mvn package:打包为构件(如jar、war包)
  • mvn install:将构件包安装到本地仓库
  • mvn deploy:将构件包部署到远程仓库

可以多个命令组合使用,如mvn clean install

执行 Maven 命令必须在 Maven 项目的根目录执行,也就是当前目录下一定存在一个名为 pom.xml 的文件。

后记

接触maven也有三年时间了,一直想详细的整理下资料,但由于懒惰与时间关系,直到现在才写出来,真的感到汗颜。
以上也只是对maven的一个大致介绍,更详尽的内容,请参考Maven官方文档

感谢Maven,感谢Jason van Zyl




如果您觉得这篇文章对您有所帮助, 点我, 可以请我喝杯咖啡。
< 支付宝 | 微信 >
Published with Hexo and Theme by Kael
Flag Counter
X