发发同学的博客

Maven的基本使用

Maven介绍

Maven介绍

Maven是apache旗下的开源工具,采用Project Object Model(POM)概念来管理项目,配置信息是都被定义在pom.xml文件。

Maven解决什么问题

  • jar包的声明式依赖与管理
  • 自动构建项目

Maven配置

Maven软件目录

  • lib:共享库,maven软件依赖的lib jar包
  • boot:plexus-classworlds-2.5.2.jar

    该文件是jar包下载的引擎,通过该工具来下载jar包

    • 第三方项目依赖的jar包
    • maven本身的软件构建的生命周期插件的jar包
  • conf:settings.xml

    maven的配置文件主要配置下面几个:

    • 配置的是本地仓库地址
    • jar包的远程的下载仓库地址
    • 配置服务器

Maven规约的目录结构,java项目结构如下

java项目

  • src
    • main
      • java
        • 包和类 包 com.xxx 类 Demo.java
      • resources 资源文件
    • test
      • java
      • resources
  • target 该文件夹可有可无,是编译src后的输出文件的目录,没有则自动创建
  • pom.xml 项目对象模型,它是maven核心配置文件

生命周期命令插件构建项目

首先进入项目文件目录

生命周期命令:

有三个内置生命周期

  • 默认的(default)
    • mvn validate : 验证项目是否正确,所有必要的信息可用
    • mvn process-resources 把代码复制到目标目录下,为以后打包用
    • mvn compile : 编译项目的源代码
    • mvn test : 用合适的单元测试框架测试编译的源代码。这些测试不应该要求代码被打包或部署
    • mvn package : 打包
    • mvn integration-test:: 将包过程并部署到可以运行集成测试的环境中
    • mvn verify : 对集成测试的结果执行任何检查,以确保满足质量标准
    • mvn install : 安装到本地仓库
    • mvn deploy : 部署
  • 清除(clean)
    • mvn clean : 清除
  • 站点(site)
    • mvn site :生产该项目的站点文档

maven坐标

maven通过坐标的概念来唯一标识jar包或者war包
坐标的组成:gourpId + artifactId + Version

  • groupId 组id,机构名,公司名
  • artifactId 构建物id,产品名或者产品的id
  • version 版本号

Maven配置

配置本地仓库

<localRepository>这里是你定义的本地仓库地址</localRepository>

配置远程仓库

默认的第三方jar包下载地址http://repo.maven.apache.org/maven2

假如我们要使用阿里云的public repository的话,我们可以在maven的settings.xml中,加入如下配置,就可以使用阿里云提供的镜像库了。具体配置如下:

  • <mirrors>元素里面加一个<mirror>配置
1
2
3
4
5
6
<mirror>
<id>aliyun</id>
<mirrorOf>centeral</mirrorOf>
<name>aliyun mirror</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
</mirror>
  • <profiles>中加一个<profile>配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<profile>
<id>aliyun</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<repositories>
<repository>
<id>aliyun</id>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>aliyun</id>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
</pluginRepository>
</pluginRepositories>
</profile>

Maven使用

新建webapp项目

1
mvn archetype:generate -DgroupId=com.zhangyifa.restaurant -DartifactId=Restaurant -Dpackage=com.zhangyifa -Dversion=1.0.0-SNAPSHOT -DarchetypeArtifactId=maven-archetype-webapp

新建java项目

1
mvn archetype:generate -DgroupId=com.zhangyifa.restaurant -DartifactId=Kitchen -Dpackage=com.zhangyifa -Dversion=1.0.0-SNAPSHOT -DarchetypeArtifactId=maven-archetype-quickstart

maven pom文件详解

pom.xml基本标签

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<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">
<!--pom 版本-->
<modelVersion>4.0.0</modelVersion>
<!--组id
maven 用坐标概念来标识 jar包
坐标=groupId+artifactId+version
-->
<groupId>com.zhangyifa.maven</groupId>
<!--构建物id :产品id-->
<artifactId>HelloWorld/artifactId>
<!--版本 :SNAPSHOT :测试版本 ,镜像版本 RELEASE :发行版本,最终版本-->
<version>0.0.1-SNAPSHOT</version>
<!--发布的是jar包 ,默认是jar包,也可以使war包和pom-->
<packaging>jar</packaging>
<!--项目名称 ,可写可不写-->
<name>Hello</name>
<dependencies>
<!--jar包声明式依赖 依赖 junit4.9jar包-->
<dependency>
<!--用坐标来标识jar包: 坐标=groupId+artifactId+version -->
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version>
<!--依赖的jar包的使用范围 : 当测试时使用该jar包
test 、 compile(默认)
-->
<scope>test</scope>
</dependency>
<!--jar包声明式依赖 依赖 Hello.jar包-->
<dependency>
<!--用坐标来标识jar包: 坐标=groupId+artifactId+version -->
<groupId>com.zhangyifa.maven</groupId>
<artifactId>Hello</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

pom.xml文件的默认配置在lib\maven-model-builder-3.5.0.jar里面的pom.xml

项目里面所有新建的pom.xml都从这里super pom继承而来

查看pom继承项
mvn help:effective-pom

dependency的scope作用域详解

  1. test 范围指的是测试范围有效,在编译和打包时都不会使用这个依赖,只在测试时使用,用于编译和运行测试代码。不会随项目发布。

  2. compile 范围指的是编译范围有效,在编译和打包时都会将依赖存储进去,会随着项目一起发布,缺省值

  3. provided 在编译和测试的过程有效,最后生成war包时不会加入,诸如:servlet-api,因为servlet-api,tomcat等web服务器已经存在了,如果再打包会冲突 。同时没有传递性,即:child module无法引用。

  4. runtime 在运行的时候依赖,在编译的时候不依赖 ,如JDBC驱动,适用运行和测试阶段。

  5. system 跟provided 相似,但是在系统中要以外部JAR包的形式提供,maven不会在repository查找它。 注意:此标记已被弃用

  6. import 此范围仅在类型为pom的依赖关系支持在部分。它指示要替换为指定POM的部分中的依赖关系的有效列表的依赖关系。由于它们被替换,具有import范围的依赖关系实际上并不参与限制依赖关系的传递性。

注意:间接依赖问题:依赖的jar包必须是compile范围,假如是test范围,则发布的jar包不会包含test范围依赖的jar包和依赖关系

dependencyManagement使用

  1. 在Maven中dependencyManagement的作用其实相当于一个对所依赖jar包进行版本管理的管理器。
  2. pom.xml文件中,jar的版本判断的两种途径
    • 如果dependencies里的dependency自己没有声明version元素,那么maven就
      会倒dependencyManagement里面去找有没有对该artifactId和groupId进行过版本声明,如果有,就继承它,如果没有就会报错,告诉你必须为dependency声明一个version
    • 如果dependencies中的dependency声明了version,那么无论dependencyManagement中有无对该jar的version声明,都以dependency里的version为准。

pom继承

我们可以通过pom来管理多个子pom

实例

父pom

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<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>com.zhangyifa.restaurant</groupId>
<artifactId>restaurant-parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name> Multi modules demo </name>
<modules>
<module>Restaurant</module>
<module>Kitchen</module>
</modules>
<properties>
<junit.version>4.3</junit.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>compile</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>

子Restaurant的pom,这是一个webapp项目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
<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>com.zhangyifa.restaurant</groupId>
<artifactId>Restaurant</artifactId>
<packaging>war</packaging>
<version>1.0.0-SNAPSHOT</version>
<name>Restaurant Maven Webapp</name>
<url>http://maven.apache.org</url>
<parent>
<groupId>com.zhangyifa.restaurant</groupId>
<artifactId>restaurant-parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>com.zhangyifa.restaurant</groupId>
<artifactId>Kitchen</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<finalName>Restaurant</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-compiler-plugin</artifactId>
<version>2.2</version>
<configuration>
<uriEncoding>UTF-8</uriEncoding>
<url>http://localhost:8080/manager/text</url>
<server>tomcat</server>
</configuration>
</plugin>
</plugins>
</build>
</project>

子Kitchen的pom,这是java项目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<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>com.zhangyifa.restaurant</groupId>
<artifactId>Kitchen</artifactId>
<packaging>jar</packaging>
<version>1.0.0-SNAPSHOT</version>
<name>Kitchen</name>
<url>http://maven.apache.org</url>
<parent>
<groupId>com.zhangyifa.restaurant</groupId>
<artifactId>restaurant-parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
</dependencies>
</project>

Maven插件

help

mvn help:describe -Dplugin=<plugin_name> -Dgoal=<goal> -Ddetail=true

mvn help:describe -Dplugin=compiler -Dgoal=compile -Ddetail=true

mvn help:help -Ddetail=true

mvn help:describe -Dplugin=tomcat7

exec

mvn exec:java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<goals>
<goal>java</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>com.zhangyifa.Kitchen</mainClass>
</configuration>
</plugin>

mvn exec:exec

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
<configuration>
<executable>java</executable>
<arguments>
<argument>-classpath</argument>
<classpath></classpath>
<argument>com.zhangyifa.Kitchen</argument>
</arguments>
</configuration>
</plugin>

Maven部署

可以通过Maven一键部署到tomcat服务器
$CATALINA_HOME/conf/tomcat-users.xml 的文件里面 <tomcat-users> 标签里面添加

1
2
3
<role rolename="manager-gui"/>
<role rolename="manager-script"/>
<user username="tomcat" password="123456" roles="manager-script,manager-gui"/>

$MAVEN_HOME/conf/settings.xml 的文件里面 <servers> 标签里面添加

1
2
3
4
5
<server>
<id>tomcat</id>
<username>tomcat</username>
<password>123456</password>
</server>

项目的pom.xml的文件里面 <build> 里面的 <plugins> 标签里面添加

1
2
3
4
5
6
7
8
9
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<url>http://localhost:8080/manager/text</url>
<server>tomcat</server>
</configuration>
</plugin>

指令部署:mvn tomcat7:deploy

重新指令部署:mvn tomcat7:redeploy

解除指令部署:mvn tomcat7:undeploy

参考链接

Maven 5分钟入门
部署tomcat
Maven中的dependencyManagement意义
scope作用域详解
Exec Maven Plugin全面解析和使用示例
使用Maven运行Java main的3种方式