首页 > 代码库 > Maven

Maven

Maven简介

Maven的两个核心概念:坐标和依赖。

Maven坐标

通过一些元素进行定义,包括groupId、artifactId、version、packaging、classifier。

依赖范围

依赖范围主要用来控制与三种classpath(编译classpath、测试classpath、运行classpath)的关系。

  • compile: 编译依赖范围

  • test: 测试依赖范围

  • provided: 已提供依赖范围,例如Servlet-api,编译和测试需要,但运行时由容器提供,不需重复引入

  • runtime: 运行时依赖

  • system: 系统依赖范围;主要涉及本机系统绑定

  • import: 导入依赖范围

Maven仓库

坐标和依赖是任何一个构件在Maven世界中的逻辑表示方式,构件的物理表示方式是文件,Maven通过仓库来统一管理这些文件。

-仓库布局 大致为:groupId/artifactId/version/artifactId-version.packaging

-仓库分类 对Maven来说,只分为本地参考和远程仓库。Maven查找构件次序:优先本地仓库,本地无则去远程仓库查找。私服是一种特殊的远程仓库,为节省带宽和时间,应在局域网内假设一个私服

本地仓库

自定义本地仓库目录位置,例如C盘空间不足等。 修改~/.m2/setting.xml,设置localRespository元素的值

<localRepository>D:/Java/apache-maven-3.0.5/local_repos</localRepository>

默认情况下,~/.m2/settings.xml文件不存在,用户需要从Maven的安装位置,复制一份%MAVEN_HOME%/conf/settings.xml拷贝再进行编辑。

从仓库解析依赖的机制

  1. 当依赖范围是system时,Maven直接从本地文件系统解析构件

  2. 根据依赖坐标计算仓库路径后,优先尝试直接从本地仓库寻找构件

  3. 本地不存在,如果依赖版本是显式的发布版本构件,如1.2、1.2-beta-1等,则遍历所有远程仓库

  4. 如果依赖的版本是RELEASE或者LATEST,则基于更新策略读取所有远程仓库的元数据groupId/artifactId/maven-metadata.xml,将其与本地仓库的对应元数据合并后,计算出RELEASE或者LATEST真实值,然后基于这个真实值检查本地和远程仓库

  5. 如果依赖的版本是SNAPSHOT,则基于更新策略读取所有远程仓库的元数据groupId/artifactId/version/maven-metadata.xml,与本地元数据合并后得到最新快照版本的值,然后检查本地仓库,或者从远处仓库下载

  6. 如果最后解析得到的构件版本是时间戳格式的快照,如1.4.1-20091104.121450-121,则复制其时间戳格式的文件至非时间戳格式,如SNAPSHOT,并使用该非时间戳格式的构件。

当依赖的版本不明晰的时候,如RELEASE/LATEST/SNAPSHOT,Maven需要基于更新远程仓库的更新策略来检查更新

仓库搜索服务

使用Maven进行日常开发,常见问题就是如何寻找需要的依赖,我们可能只知道需要使用类库的项目名称,但添加Maven依赖需要提供确切的Maven坐标;我们可以通过使用仓库搜索服务来根据关键字得到Maven坐标。

  1. MVNrepository

  2. Sonatype Nexus

在Windows上安装Maven

检查JDK安装

echo %JAVA_HOME%
java -version       #查看Java版本

下载Maven

本地安装

  1. 将压缩包解压到指定目录中,个人建议D:/java/apache-maven-3.0.5

  2. 需要设置环境变量,将Maven安装配置到操作系统环境中

  • 设置MAVEN_HOME,指向Maven安装目录:D:/java/apache-maven-3.0.5

  • 修改PATH变量,在末尾添加";%MAVEN_HOME%/bin 检查设置

echo %MAVEN_HOME%
mvn -v               #查看Maven版本

Maven设置

  1. 全局设置,修改%MAVEN_HOME%/conf/settings.xml

  2. 用户设置(在Linux多用户情况下),拷贝%MAVEN_HOME%/conf/settings.xml到~.m2\settings.xml,修改此文件,在用户范围内定制Maven的行为。

~/.m2目录

  1. 在用户目录下可以发现.m2文件夹。默认情况,该文件夹下放置了Maven本地仓库.m2/repository,所有Maven构件被存储在本地此目录下,以方便在多个项目间重用。

  2. 在Linux多用户环境下,用户需要复制%MAVEN_HOME%/conf/settings.xml到~.m2\settings.xml,这是一条最佳实践。

    mvn help:system #打印当前Java系统属性和环境变量

设置HTTP代理

编辑settings.xml,添加代理配置如下:

<proxy>
  <id>optional</id>
  <active>true</active>
  <protocol>http</protocol>
  <username>proxyuser</username>
  <password>proxypass</password>
  <host>proxy.host.net</host>
  <port>80</port>
  <nonProxyHosts>local.net|some.host.com</nonProxyHosts>
</proxy>

Eclipse的Maven插件m2eclipse

m2eclipse插件,其中模块Maven Integrateion for WTP(Optional),可以让Eclipse自动读取POM信息,并配置WTP项目(支撑WEB应用开发)。

备注:需要配置Eclipse,调整vm配置指向本机JDK

Maven安装最佳实践

设置MAVEN_OPTS环境变量

通常需要配置MAVEN_OPTS=-Xms128m -Xmx512m,因为Java默认最大内存往往不能够不满足Maven运行的需要,否则很容易得到java.lang.OutOfMemoryError.

不要使用IDE内嵌的Maven

配置maven-compile-plugin支持Java5,默认只支持编译Java1.3(pom.xml配置)

            <!-- compiler插件, 设定JDK版本 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.0</version>
                <configuration>
                    <source>1.5</source>
                    <target>1.5</target>
                    <showWarnings>true</showWarnings>
                </configuration>
            </plugin>

Maven生成可执行Jar包(pom.xml配置)

maven有两种生成可执行jar包的插件,能够自动加载依赖包。分别为 maven-assembly-plugin 和appassembler-maven-plugin。

  • appassembler-maven-plugin 的优势是能够自动生成window和linux的启动脚本

  • maven-assembly-plugin 生成jar包后需要执行 java -jar **.jar命令运行jar包。

Maven项目骨架

  • 根目录中放置pom.xml

  • src/main/java目录中,放置项目的主代码

  • src/main/resources目录中,放置项目的的资源文件,如配置文件.ini/.xml/*.propeties

  • src/test/java目录中,放置项目的测试代码

排除依赖(pom.xml配置)

    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.15</version>
        <exclusions>
            <exclusion>
                <groupId>javax.jms</groupId>
                <artifactId>jms</artifactId>
            </exclusion>
            <exclusion>
                <groupId>com.sun.jdmk</groupId>
                <artifactId>jmxtools</artifactId>
            </exclusion>
            <exclusion>
                <groupId>com.sun.jmx</groupId>
                <artifactId>jmxri</artifactId>
            </exclusion>
            <exclusion>
                <groupId>javax.mail</groupId>
                <artifactId>mail</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

归类依赖(pom.xml配置)

    <properties>
        <!-- 主要依赖库的版本定义 -->
        <cxf.version>2.7.4</cxf.version>
    </properties>
    <!-- SOAP begin -->
    <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-rt-core</artifactId>
        <version>${cxf.version}</version>
        <exclusions>
            <!-- use javax.mail.mail instead -->
            <exclusion>
                <groupId>org.apache.geronimo.specs</groupId>
                <artifactId>geronimo-javamail_1.4_spec</artifactId>
            </exclusion>
            <!-- use javax.activation.activation instead -->
            <exclusion>
                <groupId>org.apache.geronimo.specs</groupId>
                <artifactId>geronimo-activation_1.1_spec</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-rt-frontend-jaxws</artifactId>
        <version>${cxf.version}</version>
        <exclusions>
            <!-- see above -->
            <exclusion>
                <groupId>org.apache.geronimo.specs</groupId>
                <artifactId>geronimo-javamail_1.4_spec</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.apache.geronimo.specs</groupId>
                <artifactId>geronimo-activation_1.1_spec</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-rt-transports-http</artifactId>
        <version>${cxf.version}</version>
    </dependency>
    <!-- SOAP end -->

约定优于配置

Maven提倡“约定优于配置”(Convention Over Configuration),这是Maven最核心的设计理念之一。原因之一是,使用约定可以大量减少配置。

对Maven 3,超级POM在文件$MAVEN_HOME/lib/maven-model-builder-x.x.x.jar中的org/apache/maven/model/pom-4.0.0.xml路径下。主要定义包括:

  • 仓库及插件仓库

  • 超级POM中关于项目结构约定的定义,包括:项目的主输出目录、主代码输出目录、最终构件的名称格式、测试代码输出目录、主源码目录、脚本源码目录、测试源码目录、主资源目录和测试资源目录。

  • 核心插件版本设定

  • 项目报告输出目录

  • 项目发布的profile

依赖优化(pom.xml配置)

mvn dependency:list     #查看项目已解析依赖(Resolved Dependency)
mvn dependency:tree     #查看当前项目的依赖树
mvn dependency:analyze  #工具帮助分析当前项目的依赖,重点关注"Used undeclared dependencies"和"Unused declared depend


Maven