Maven入门摘要

最近写了太多的类似“浅尝XX”、“了解XX”、“XX入门”之类的文章,说句真心的我自己都想吐了,但是也没办法,我一个牛逼哄哄的Android工程师被当做一个纯后端使用,一堆新的概念和知识等着去学习,白天看知识点看的脑子都不灵光了,只能晚上再回忆一遍,写下来强记一下。

Maven 是现在后端常用的包管理和编译系统,本篇会系统性的介绍Maven相关的知识。本文的知识节选自:

Maven工程

在我们使用maven作为包管理系统的时候,其实也默认了使用maven风格的工程结构,这样的工程结构和Eclipse默认的工程结构区别还是挺大的,典型的maven风格:

my-app
|-- pom.xml
`-- src
    |-- main
    |   `-- java
    |       `-- com
    |           `-- mycompany
    |               `-- app
    |                   `-- App.java
    `-- test
        `-- java
            `-- com
                `-- mycompany
                    `-- app
                        `-- AppTest.java

工程根目录为 my-app 在工程目录下面会有一个 pom.xml 文件用来描述工程的属性和依赖等等。工程按 src/main/java/ 作为源码路径,src/test/java/ 为测试项目路径,如果还有一些资源文件需要打在jar包中,路径默认为 src/main/resources/META-INF/

可以手动建立这样的目录,也可以使用maven的命令自动生成:

mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-app -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

这条命令需要传入3个命令行参数:

  • -DgroupId={project-packaging} 需要传入工程的包名
  • -DartifactId={project-name} 需要传入工程名
  • -DarchetypeArtifactId=maven-archetype-quickstart 创建工程时参照的模板,如果不指定模板的话,会给出一个很长的模板列表供选择

注:’-DinteractiveMode=false’ 的意思是禁用交互式模式

此时查看一下生成的模板工程中的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>
 
  <groupId>com.mycompany.app</groupId>
  <artifactId>my-app</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>
 
  <name>Maven Quick Start Archetype</name>
  <url>http://maven.apache.org</url>
 
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.8.2</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

这个最简的POM文件很有说明性,可以分成三部分:

  1. “groupId/artifactId/version” 是一部分,它描述了一个工程的完整面貌
  2. “packaging” 描述了打包方式,即执行 mvn package 的时候如何打包
  3. “dependency” 描述了依赖关系,这里个工程依赖于junit测试框架(通过“groupId/artifactId/version”来描述,这样maven就可以在仓库中找到这个框架 )

注:依赖里面有个 ‘scope’ 配置,它描述了这个依赖的覆盖范围,此处为仅在测试时候使用,scope还有其它的既定的选择,它是一个枚举类型。

常用的几个maven命令:

  1. mvn package 打包
  2. mvn deploy 把包部署到服务器(当然要先配置好服务器地址)
  3. mvn clean 清空缓存和临时文件
  4. mvn install 把包安装到本地的maven仓储
  5. mvn compile 编译源码
  6. mvn test 执行测试

配置插件

在上面的工程中,我们执行 mvn package的时候,会触发 <packaging>jar</packaging> 对源码进行编译打包(输出为一个jar包),jar是maven内置的一种打包插件,如果我们希望打的包是其它格式的(比如war包),那又怎么办到呢?这便是插件的用武之地了!

比如用插件来打一个war包:

...
<build>
  <plugins>
    <plugin>
       <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-war-plugin</artifactId>
        <version>2.6</version>
        <configuration>
            <packagingExcludes>public/**,view/**</packagingExcludes>
            <webResources>
                <resource>
                    <directory>src/main/webapp/public</directory>
                    <filtering>false</filtering>
                </resource>
            </webResources>
        </configuration>
    </plugin>
  </plugins>
</build>
...

插件的添加格式大概如上面所示,添加新的插件的时候按照上面的格式即可,如何去获得自己需要的插件呢?这有两种途径,一种自己写一个,另外是在Maven的Plugins List里面找到自己需要的即可(因为大部分的maven任务都是雷同的,所以这里准备的插件可以满足绝大多数的需求)。

如果我们希望改变内置过程的一些编译条件,也可以用插件的方式来完成:

...
<build>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-compiler-plugin</artifactId>
      <version>3.3</version>
      <configuration>
        <source>1.5</source>
        <target>1.5</target>
      </configuration>
    </plugin>
  </plugins>
</build>
...

这样设置,让我们的源码编译条件指定为Java1.5。

依赖

在最开的示例中,已经见到了依赖的pom格式,

<dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.8.2</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

大体上依赖可以分成3种:

  1. maven仓储中的包依赖
  2. 本地包(非本地仓储)依赖
  3. 工程依赖

第一种是大家司空见惯的依赖方式,比如上面对junit的依赖便是,这种方式会从maven的中央仓储下载jar包到本地仓储,只要按照 “groupId/artifactId/version” 的方式填写依赖便没有问题。

第二种情况一般出现在你自己有一个jar包,但是这个jar不在maven的中央仓库库里面,如果需要添加这个依赖的话,可以在工程目录下建立一个libs目录,把用到的jar包手动拷贝到这个目录下,然后在依赖里面配置依赖为本地路径:

<dependency>
    <groupId>com.alipay.mycar.demo</groupId>
    <artifactId>interface</artifactId>
    <version>0.0.1</version>
    <type>jar</type>
    <scope>system</scope>
    <systemPath>${project.basedir}/libs/interface-0.0.1.jar</systemPath>
</dependency>

这时候maven是从本地路径加载的jar包,这时候 “com.alipay.mycar.demo/artifactId/version” 都可以随便写的,并且一定要注意“<scope>system</scope>”是必须的。如果使用 mvn compile 编译源码,经常会发现这样的警告:

[WARNING] Some problems were encountered while building the effective model for com.mycompany.app:my-app:jar:1.0-SNAPSHOT
[WARNING] 'dependencies.dependency.systemPath' for com.alipay.mycar.demo:interface:jar should not point at files within the project directory, ${project.basedir}/libs/interface-0.0.1.jar will be unresolvable by dependent projects @ line 17, column 21

官方虽然提供了这种方式来依赖本地jar包,但是却又十分的不推荐,官方给出的做法是用mvn install命令把jar安装到本地仓储:

mvn install:install-file -Dfile=non-maven-proj.jar -DgroupId=some.group -DartifactId=non-maven-proj -Dversion=1 -Dpackaging=jar

其实还有一种做法,可以参考这里的文档.

第三种情况工程依赖是另一个比较重要的问题,它往往出现在多工程配置的情况,下面小节会介绍这种情况。

多工程配置

Maven的多工程配置约定是这样的:

+- pom.xml
+- my-app
|   +- pom.xml
|   +- src
|     +- main
|       +- java
+- my-webapp
|   +- pom.xml
|   +- src
|     +- main
|       +- webapp

最外层是工程的根目录,根目录下面配置一个pom.xml文件,每个子工程都是独立的文件夹(这里的子工程分别是 my-appmy-webapp),每个子工程的根目录下面还需要再配置各自的 pom.xml 文件。

父工程的POM文件:

// 父目录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>
 
  <groupId>com.mycompany.app</groupId>
  <artifactId>app</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>pom</packaging>
// 在此配置了子工程的目录
  <modules>
    <module>my-app</module>
    <module>my-webapp</module>
  </modules>
</project>

子工程的POM文件:

<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">
  <parent>
    <groupId>com.mycompany.app</groupId>
    <artifactId>app</artifactId>
    <version>1.0-SNAPSHOT</version>
  </parent>
  ...

特殊的地方在于父工程中需要声明子工程的存在,同样子工程中需要声明自己的父工程是谁。上一节中曾经遗留了一个问题:工程间的依赖如何配置?

假设我们的 my-webapp 依赖于 my-app ,那么可以在 my-webapp 的POM文件中做如下的依赖配置:

...
  <dependencies>
    <dependency>
      <groupId>com.mycompany.app</groupId>
      <artifactId>my-app</artifactId>
      <version>1.0-SNAPSHOT</version>
    </dependency>
    ...
  </dependencies>

注:好像并没有特别意外的地方…

更多

关于Maven的配置基本都集中在这几份文档里面了:

    原文作者:ntop
    原文地址: https://www.jianshu.com/p/d3bfeaf92a9c
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞