概述
介绍
Maven
是Apache
下的一个开源项目,用于Java
平台的项目构建与管理。Maven
基于POM(Project Object Model)
概念,使用中央信息管理一整个项目的构建、依赖和项目打包等工作。Maven
项目中,任何一个依赖、插件或项目构建的输出都称为构件,构件相当于Maven
构建项目的原材料。
Maven
仓库
Maven
仓库指存放项目构件(JAR,WAR,POM,ZIP...
)的位置,Maven
仓库分为两大类型:本地仓库和远程仓库,远程仓库分为中央仓库,私服仓库和其它公共仓库三种。Maven
根据坐标寻找目标构件时,首先在本地仓库查找,如果本地仓库存在目标构建则直接使用,不存在则在远程仓库中继续查找。
本地仓库即存储在本地硬盘上的构件仓库;中央仓库是由Maven
社区提供的网上仓库,包含了大量常用的库;私服仓库是公司自己搭建在局域网中的仓库。
多模块构建
DAO,Service,Controller
层分离将一个项目分解为多个模块,是目前很通用的Web
工程模块化项目管理方式,Maven
可以使用简单的命令生成并管理项目模块。
一致的项目结构
不同的项目编辑器(例如IDEA
与Eclipse
)构建项目时的工程目录不一致,导入另一个编辑器上的项目时可能因为工程文件不兼容产生错误。Maven
的设计理念为约定大于配置,制定了一套项目目录作为Java
项目的项目结构标准,从而解决不同编辑器项目结构不一致的问题。
插件机制
Java
项目可能会涉及到很多必要的插件,例如Tomcat
服务器,可使用编辑器整合插件,而Maven
提供了通过命令整合插件的方式,使得项目更加独立,不依赖于具体的编辑器。
Maven
的安装与配置
Maven
下载
Maven
基础配置
下载完成后解压在自定义目录中即可完成安装。Maven
配置步骤:
1.在系统环境变量中添加"MAVEN_HOME",路径指向Maven的安装(解压)目录
2.将路径"Maven安装(解压)目录/bin"添加至系统环境变量的Path变量中
3.打开dos窗口,输入"mvn -v"并回车,如果弹出Maven版本信息则Maven配置成功
修改仓库位置
Maven
仓库默认为国外的Maven
官网的仓库(http://search.maven.org
),下载构件时会比较慢,可以通过配置文件将Maven
仓库设置为国内的阿里云Maven
仓库。具体方法是修改Maven安装(解压)目录/conf/settings.xml
.
settings.xml
<?xml version="1.0" encoding="UTF-8"?>
<settings ... >
...
<!-- localRepository指定本地仓库的路径,注意路径分隔符使用"/".
Maven运行时,会将组件先从远程镜像仓库中下载构件到本地仓库,再使用本地仓库构建项目 -->
<localRepository>D:/mvnrep</localRepository>
...
<mirrors>
<!-- 默认仓库镜像
<mirror>
<id>maven-default-http-blocker</id>
<mirrorOf>external:http:*</mirrorOf>
<name>Pseudo repository to mirror external repositories initially using HTTP.</name>
<url>http://0.0.0.0/</url>
<blocked>true</blocked>
</mirror>
-->
<!-- 阿里云仓库镜像 -->
<mirror>
<id>nexus-aliyun</id>
<!-- 指定此镜像为Maven中央仓库的镜像 -->
<mirrorOf>central</mirrorOf>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
</mirrors>
...
</settings>
修改编译环境
Maven
可以使用settings.xml
文件指定默认编译环境,例如jdk
版本等信息:
settings.xml
<?xml version="1.0" encoding="UTF-8"?>
<settings ... >
...
<profiles>
<profile>
<id>jdk-1.8</id>
<activation>
<!-- 声明此环境为默认 -->
<activeByDefault>true</activeByDefault>
<jdk>1.8</jdk>
</activation>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
<!-- 源码编码格式 -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</profile>
...
</profiles>
...
</settings>
Maven
基础
Maven
仓库
Maven
坐标
坐标是Maven
构件最重要的属性,是Maven
构件在本地仓库及远程仓库的资源路径的映射。工程或模块添加依赖及添加插件时最重要的参数即为Maven
坐标。Maven
坐标由groupId,artifactId和version
组成。
<!-- Maven构件的坐标由 groupId && artifactId && version 共同确定 -->
<dependency>
<!-- 项目组标识,一般为公司域名的倒置 -->
<groupId>com.myoner</groupId>
<!-- 项目标识,一般与项目名相同 -->
<artifactId>HelloWorld</artifactId>
<!-- 项目版本号,格式为"X.X.X-里程碑" -->
<version>1.0.0-SNAPSHOT</version>
...
</dependency>
仓库镜像
Maven
仓库镜像指存储在镜像服务器上的Maven
仓库,镜像服务器指与某个服务器内容完全一致且保持同步数据更新,但位置不同的服务器。镜像服务器的搭建主要为了解决服务器访问困难的问题,例如阿里云Maven
镜像的搭建即为了解决Maven
中央仓库访问困难的问题。
Maven
项目结构
目录结构
除了项目根目录(${basedir}
)为自定义外,Maven
制定了一套目录标准:
目录 | 作用 |
---|---|
${basedir} | 存放pom.xml和所有子目录 |
${basedir}/src/main/java | 存放项目的Java源码 |
${basedir}/src/main/resources | 存放项目的资源文件,例如property文件 |
${basedir}/src/test/java | 存放项目的测试类,例如JUnit代码 |
${basedir}/src/test/resources | 存放项目测试使用的资源文件 |
例:
HelloWorld
|---src
|---main
|---java
|---resources
|---test
|---java
|---resources
|---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/xsd/maven-4.0.0.xsd">
<!-- POM模型版本,目前只能是4.0.0 -->
<modelVersion>4.0.0</modelVersion>
<!-- groupId指定当前项目组,项目组ID是项目的全球唯一标识,通常使用"com.公司名定义" -->
<groupId>com.baidu</groupId>
<!-- artifactId指定当前项目在项目组中的唯一标识 -->
<artifactId>mavenTest-1.0</artifactId>
<!-- version指定项目版本,即项目的更新版本,由版本号和里程碑组成。各个符号解释如下:
第1个X : 大版本,项目有重大变革;
第2个X : 小版本,修复bug,增加功能;
第3个X : 更新。
里程碑:
SNAPSHOT : 快照,开发版;
alpha : 内测版;
beta : 公测版;
Release/RC : 发布版;
GA : 正常版 -->
<version>X.X.X-SNAPSHOT</version>
<!-- packaging指定项目产生的构件类型,常用有jar,war,ear,pom等 -->
<packaging>jar</packaging>
<!-- test用于声明一个对于用户而言更加友好的项目名称,Maven产生文档时使用 -->
<name>test</name>
<!-- 项目主页的url,Maven产生文档时使用 -->
<url>http://baidu.com/mavenTest</url>
<!-- 项目配置 -->
<properties>
<!-- 指定源码的文本编码格式 -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<!-- 项目依赖 -->
<dependencies>
<dependency>
<!-- 依赖构件的项目组标识 -->
<groupId>com.myoner</groupId>
<!-- 依赖构件的项目标识 -->
<artifactId>HelloWorld</artifactId>
<!-- 依赖构件的版本号 -->
<version>1.0.0-SNAPSHOT</version>
<!-- 依赖构建的作用范围:
compile - 编译依赖范围,对编译、测试、运行均有效,默认值;
test - 测试依赖范围,仅对测试有效;
provided - 已提供依赖范围,只对编译和测试有效,构件依赖的作用范围已被第三方提供,
例如servlet-api的依赖范围已被Tomcat容器提供;
runtime - 运行时依赖范围,只对测试和运行有效 -->
<scope>test</scope>
</dependency>
</dependencies>
</project>
Maven
构建项目
常用Maven
命令
Maven
支持命令行形式的工程构建。常用命令有:
/* 查看Maven版本信息 */
mvn -v
/* 编译工程 : 定位到工程根目录,在窗口的文件路径栏中输入"cmd",执行编译命令,
第一次运行时会先从指定的仓库镜像中下载构件 */
mvn compile
/* 执行main方法,参数输入main方法所在类的全类名 */
mvn exec:java -Dexec.mainClass="com.test.demo.Main"
/* 清理项目产生的临时文件,一般是模块下的target目录 */
mvn clean
/* 项目打包,会在模块下的target目录中生成指定的打包文件 */
mvn package
/* 测试命令,执行src/test/java下的JUnit测试用例 */
mvn test
/* 将打包的jar/war文件复制到本地仓库,供其他模块使用 */
mvn install
/* 将打包的文件发布到远程参考,提供其他人员下载依赖 */
mvn deploy
/* 生成项目相关信息的网站 */
mvn site
/* 打印项目的依赖树 */
mvn dependency:tree
/* 创建Java普通项目 */
mvn archetype:generate
/* 在Tomcat容器中运行web项目 */
mvn tomcat7:run
在IEDA
中运行Maven
时,需要点击运行按钮旁边的Edit Configurations
添加Maven
命令才能正确运行项目,注意此时添加的Maven
命令需要去除以上命令之前的"mvn"
.
IDEA
集成Maven
普通Java
项目
IDEA
配置Maven
环境:
1.依次点击File -> New Projects Settings -> Settings for New Projects ->
Buile,Execution,Deployment -> Build Tools -> Maven
2.选择Maven home directory,定位Maven的安装(解压)目录
3.选择User settings file,勾选右侧的Override,定位Maven安装(解压)目录/conf/settings.xml
4.选择Local repository,勾选右侧的Override,定位Maven本地仓库目录
Maven
创建普通Java
项目:
1.依次点击File -> New -> Project
2.在弹出的窗口中选择Maven
3.选择Project SDK,指定JDK版本
4.勾选Create from archetype(从模板创建),
选择org.apache.maven.archetypes:maven-archetype-quickstart
5.点击Next,输入项目名和项目位置
6.在Artifact Coordinates中输入仓库信息:
GroupId指定项目组标识,一般为"com.公司名";
ArtifactId指定当前项目在项目组下的标识,一般为"项目名";
Version指定工程版本,格式为"X.X.X-里程碑"
7.配置Maven环境(如果之前IDEA成功配置了Maven环境,此步会自动配置完善)
8.为src/main和src/test中添加resources目录:
(1).新建resources目录
(2).右击新建的resources目录,选择Mark Directory as,选择Resources Root
Maven
运行普通Java
项目:
1.点击运行按钮左侧的Edit Configurations
2.点击"+",选择Maven
3.在Name输入框输入命令名(自定义名称,用于运行时选择区分)
4.在Working directory输入框中选择目标工作路径
5.在Command line中输入Maven命令:
compile - mvn compile,Maven编译命令
package - mvn package,Maven打包命令
clean - mvn clean,Maven清理命令
6.在运行按钮旁边选择定义的Maven命令,运行工程
JavaWeb
项目
Maven
创建JavaWeb
项目:
01.依次点击File -> New -> Project
02.在弹出的窗口中选择Maven
03.选择Project SDK,指定JDK版本
04.勾选Create from archetype(从模板创建),
选择org.apache.maven.archetypes:maven-archetype-webapp
05.点击Next,输入项目名和项目位置
06.在Artifact Coordinates中输入仓库信息:
GroupId指定项目组标识,一般为"com.公司名";
ArtifactId指定当前项目在项目组下的标识,一般为"项目名";
Version指定工程版本,格式为"X.X.X-里程碑"
07.配置Maven环境(如果之前IDEA成功配置了Maven环境,此步会自动配置完善)
08.为src/main中添加java目录和resources目录:
(1).新建java目录
(2).右击新建的java目录,选择Mark Directory as,选择Source Root
09.为src添加test目录
10.为src/test中添加java目录和resources目录:
(1).新建resources目录
(2).右击新建的resources目录,选择Mark Directory as,选择Resources Root
11.打开pom.xml,修改JDK版本:
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
12.修改junit版本:
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
13.删除<pluginManagement>...</pluginManagement>
Maven
配置Tomcat
Maven
使用pom.xml
以插件的形式配置Tomcat
服务器,运行时Maven
会自动下载JavaWeb
工程依赖的构件。对于具体的Tomcat
版本,插件配置信息可以在Tomcat
官网的Maven Plugin
中复制。
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project ... >
...
<build>
...
<plugins>
...
<!-- Tomcat服务器插件 -->
<plugin>
<!-- 插件参数 -->
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<!-- Tomcat服务器参数 -->
<configuration>
<!-- 端口号 -->
<port>8080</port>
<!-- 站点对外访问路径,必须是以"/"开头的字符串 -->
<path>/test</path>
<!-- 字符集编码,默认为ISO-8859-1 -->
<uriEncoding>UTF-8</uriEncoding>
<!-- 服务器名 -->
<server>tomcat7</server>
</configuration>
</plugin>
...
</plugins>
...
</build>
...
</project>
Maven
运行JavaWeb
项目:
1.点击运行按钮左侧的Edit Configurations
2.点击"+",选择Maven
3.在Name输入框输入命令名(自定义名称,用于运行时选择区分)
4.在Working directory输入框中选择目标工作路径
5.在Command line中输入Maven命令"tomcat7:run"
6.在运行按钮旁边选择定义的Maven命令,运行Tomcat服务器
Maven
多模块项目
以MVC
模式为例,常用的JavaWeb
工程模块结构为:
parent
|---pom.xml
|---dao
|---pom.xml
|---...
|---service
|---pom.xml
|---...
|---controller
|---pom.xml
|---...
parent
为父模块,用于管理子模块,dao
层用于实现数据库访问,是普通的Java
项目;service
层用于实现业务逻辑,是普通的Java
项目;controller
层用于处理请求和响应,是JavaWeb
项目。父模块下三层之间的依赖关系是:controller
层调用service
层,service
层调用dao
层。
多模块构建
1.创建parent模块
(1).File -> New -> Project -> Maven,不选择模板(不勾选Create from archetype)
(2).设置项目名称、工作空间等
(3).设置项目坐标和版本
2.在parent模块下创建dao模块
(1).右击parent -> New -> Module -> Maven
(2).选择普通Java项目模板(勾选Create from archetype,
并选择org.apache.maven.archetypes:maven-archetype-quickstart)
(3).设置模块名称、工作空间
(4).设置模块坐标和版本
(5).配置Maven
3.在parent模块下创建service模块
(1).右击parent -> New -> Module -> Maven
(2).选择普通Java项目模板(勾选Create from archetype,
并选择org.apache.maven.archetypes:maven-archetype-quickstart)
(3).设置模块名称、工作空间
(4).设置模块坐标和版本
(5).配置Maven
4.在parent模块下创建controller模块
(1).右击parent -> New -> Module -> Maven
(2).选择JavaWeb项目模板(勾选Create from archetype,
并选择org.apache.maven.archetypes:maven-archetype-webapp)
(3).设置模块名称、工作空间
(4).设置模块坐标和版本
(5).配置Maven
5.修改每个pom.xml(修改JDK版本,去除不必要的部分,添加插件等)
6.添加必要文件夹(src/main和src/test中的java文件夹和resources文件夹)
多模块依赖
MVC
模式中,controller
层需要调用service
层中的方法,service
层需要调用dao
层中的方法。因此依赖关系是:controller
模块依赖service
模块,service
模块依赖dao
模块。
dao
层添加测试类:
package com.test.dao;
import ... ;
public class DaoTest {
public static void daoTest() {
System.out.println("Hello world,I am dao module.");
}
}
service
层添加依赖:
<dependency>
<groupId>com.test</groupId>
<artifactId>dao</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
service
层添加测试类:
package com.test.service;
import ... ;
public class ServiceTest {
public static void serviceTest() {
System.out.println("Hello world,I am service module.");
DaoTest.daoTest();
}
}
controller
层添加依赖:
<!-- service层依赖 -->
<dependency>
<groupId>com.test</groupId>
<artifactId>service</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- servlet依赖 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
controller
层添加插件:
<!-- Tomcat服务器插件 -->
<plugin>
<!-- 插件参数 -->
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<!-- Tomcat服务器参数 -->
<configuration>
<!-- 端口号 -->
<port>8080</port>
<!-- 站点对外访问路径,必须是以"/"开头的字符串 -->
<path>/test</path>
<!-- 字符集编码,默认为ISO-8859-1 -->
<uriEncoding>UTF-8</uriEncoding>
<!-- 服务器名 -->
<server>tomcat7</server>
</configuration>
</plugin>
controller
层添加测试类:
package com.test.controller;
import ... ;
@WebServlet("/test")
public class ControllerTest extends HttpServlet {
protected void service(HttpServletRequest request,HttpServletResponse response)
throws ServletException,IOException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
response.getOutputStream().write("Hello world!".getBytes("UTF-8"));
System.out.println("Hello world,I am controller module.");
ServiceTest.serviceTest();
}
}
多模块运行
使用IDEA
运行Maven
项目需要添加Maven
命令,步骤如下:
1.点击运行按钮旁边下拉框中的"Edit Configurations"
2.点击"+",选择"Maven"
3.在"Name"输入框中输入自定义命令名,方便运行工程时区分
4.在"Work directory"中选择命令作用的目标目录
5.在"Command line"中输入Maven指令,例如"compile"
6.点击"Apply"和"Ok"应用
7.点击运行按钮旁边下拉框,选择自定义的命令,点击运行按钮即可执行命令
常用命令举例:
Maven命令 | 作用 |
---|---|
compile | 编译指定模块 |
package | 将指定模块打包 |
install | 将指定模块打包并添加至仓库 |
tomcat7:run | 运行当前版本的Tomcat服务器 |
由于多模块之间存在依赖关系,需要按照依赖顺序将被依赖的模块使用install
命令打包并添加至仓库,整个工程才能成功运行。例如对于MVC
模式的JavaWeb
项目:
1.使用install命令将dao模块打包并添加至仓库
2.使用install命令将service模块打包并添加至仓库
3.使用install命令将controller模块打包并添加至仓库
4.使用install命令将parent打包并添加至仓库
5.使用tomcat7:run命令运行服务器
Maven
深入
依赖管理
依赖传递
项目中的类型有两种:直接依赖和间接依赖。直接依赖是显式声明在dependencies
中的依赖,间接依赖是依赖传递过来的其它依赖。项目的依赖也依赖某个构件时,项目即间接依赖该构件,Maven
的这种特性即为依赖的传递。例有以下依赖结构:
<!-- 项目直接依赖dependency1和dependency2 -->
project
|---dependency1
|---dependency2
<!-- dependency1依赖dependency3 -->
depencency1
|---depencency3
<!-- dependency2依赖dependency4和dependency5 -->
dependency2
|---depencency4
|---dependency5
<!-- dependency5依赖dependency6 -->
dependency5
|---dependency6
<!-- 项目的依赖传递为 -->
project
|---dependency1
|---dependency3
|---dependency2
|---dependency4
|---dependency5
|---dependency6
<!-- 项目的总体依赖为 -->
project
|---dependency1
|---dependency2
|---dependency3
|---dependency4
|---dependency5
|---dependency6
依赖冲突
项目的所有直接依赖与间接依赖中存在相同类型不同版本的依赖的情况称为依赖冲突。例有以下依赖结构:
project
|---dependencyA(1.0.5)
|---dependencyE(2.3.3)
|---dependencyA(2.1.6)
|---dependencyE(2.3.3)
|---dependencyB(2.0.1)
|---dependencyC(3.1.0)
|---dependencyD(3.1.1)
|---dependencyC(4.1.3)
|---dependencyE(1.5.0)
依赖冲突分为直接冲突和间接冲突,间接冲突又分为同层冲突和跨层冲突,将项目的依赖展开为层级结构,项目的直接依赖为最顶层依赖,间接依赖分别为内层依赖。例将以上的依赖结构展开为层次结构:
第1层依赖:
dependencyA(1.0.5),dependencyA(2.1.6),dependencyB(2.0.1),dependencyC(4.1.3)
第2层依赖:
dependencyE(2.3.3),dependencyC(3.1.0),dependencyD(3.1.1),dependencyE(1.5.0)
冲突结果:
dependencyA(1.0.5)与dependencyA(2.1.6)直接冲突
dependencyC(4.1.3)与dependencyC(3.1.0)跨层冲突
dependencyE(2.3.3)与dependencyE(1.5.0)同层冲突
Maven
为冲突的依赖配置了不同的优先级,优先级高的依赖将覆盖优先级低的依赖。
1.配置优先 : 对于直接依赖冲突,后配置的依赖优先级高于先配置的依赖
2.层级优先 : 对于跨层依赖冲突,外层依赖优先级高于内层依赖
3.声明优先 : 对于同层依赖冲突,先声明的依赖优先级高于后声明的依赖
可选依赖
Maven
可以设置依赖为不透明,项目打包后,设置为不透明的依赖对其它项目不可见。
<dependencies>
<dependency>
<groupId>...</groupId>
<artifactId>...</artifactId>
<version>...</version>
<!-- optional设置为true(默认为false),依赖不透明,对其它项目不可见 -->
<optional>true</optional>
</dependency>
</dependencies>
排除依赖
设置依赖为不透明,只能作用于当前项目打包后依赖对其它项目不可见,而无法主动排除不需要的间接依赖。Maven
可以通过其它方式主动排除不需要的依赖。
<dependencies>
<dependency>
<groupId>...</groupId>
<artifactId>...</artifactId>
<version>...</version>
<!-- exclutions中指定多个排除依赖 -->
<exclutions>
<!-- exclusion指定具体排除的依赖 -->
<exclusion>
<!-- 通过项目组标识和项目标识指定排除的依赖,无需指定版本号 -->
<groupId>...</groupId>
<artifactId>...</artifactId>
</exclusion>
...
</exclutions>
...
</dependency>
...
</dependencies>
依赖范围
项目依赖的构件默认对所有位置均有效,可通过scope
属性设置依赖的具体作用范围。依赖范围有:
1.是否在主程序范围内有效(是否在main文件夹范围内有效)
2.是否在测试程序范围内有效(是否在test文件夹范围内有效)
3.是否参与打包(package指令范围)
常用scope
属性值:
scope | main范围 | test范围 | 参与打包 | 范例 |
---|---|---|---|---|
compile(默认) | Y | Y | Y | log4j |
test | N | Y | N | junit |
provided | Y | Y | N | servlet-api |
runtime | N | N | Y | jdbc |
scope
常用属性值解释:
compile : 指定依赖在编译、测试、运行时均需要使用。对所有位置均有效,且参与项目打包
test : 指定依赖仅在测试时使用。只对test文件夹范围有效,不参与打包
provided : 指定依赖不能在运行时使用,避免冲突,因为目标插件可能使用其它版本的依赖。
对所有位置均有效,但不参与项目打包
runtime : 指定依赖只在运行时使用,需要在运行时使用反射等技术获取,编译时则不需要。仅参与项目打包
示例:
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
模块继承
进行多模块开发时,模块可能由于开发者不同而依赖不同,Maven
支持使用父模块管理所有子模块的依赖,统一项目所需的依赖。父模块中指定依赖的具体信息(例如version,scope...
)后,子模块的依赖可以继承父模块为对应依赖指定的信息,无需重复指定。
父模块管理子模块前,需要提前声明:
pom.xml(parent)
<?xml version="1.0" encoding="UTF-8"?>
<project ... >
...
<!-- 使用modules标签声明所有子模块 -->
<modules>
<!-- 使用module标签声明具体子模块,指定子模块名 -->
<module>dao</module>
<module>service</module>
<module>controller</module>
</modules>
...
</project>
子模块需要声明父模块的相对路径:
pom.xml(childs)
<?xml version="1.0" encoding="UTF-8"?>
<project ... >
...
<parent>
<!-- 父模块的工程坐标 -->
<groupId>com.myoner</groupId>
<artifactId>HelloWorld</artifactId>
<version>1.0.0</version>
<!-- relativePath指定父模块的pom.xml文件路径 -->
<relativePath>../pom.xml</relativePath>
</parent>
...
</project>
父模块中管理依赖:
pom.xml(parent)
<?xml version="1.0" encoding="UTF-8"?>
<project ... >
...
<!-- 使用modules标签声明所有子模块 -->
<modules>
<!-- 使用module标签生命具体子模块,指定子模块名 -->
<module>dao</module>
<module>service</module>
<module>controller</module>
</modules>
<dependencyManagement>
<!-- 统一规定依赖参数 -->
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
</dependencyManagement>
...
</project>
子模块中引用依赖:
pom.xml(childs)
<?xml version="1.0" encoding="UTF-8"?>
<project ... >
...
<parent>
<!-- 父模块的工程坐标 -->
<groupId>com.myoner</groupId>
<artifactId>HelloWorld</artifactId>
<version>1.0.0</version>
<!-- relativePath指定父模块的pom.xml文件路径 -->
<relativePath>../pom.xml</relativePath>
</parent>
<dependencies>
<!-- 子模块只需要使用groupId和artifactId引用依赖,
无需指定version,scope等参数,这些参数从父模块继承 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>
</dependencies>
...
</project>
资源管理
属性定义
Maven
提供了在pom.xml
中定义属性的方法,对于某些可能经常改变的标签属性,例如依赖的version
属性,可以通过自定义属性集中管理。属性的定义方式为:
<?xml version="1.0" encoding="UTF-8"?>
<project ... >
...
<properties>
<!-- 自定义属性名,推荐使用 "项目组名.项目名.目标替换属性" 的形式 -->
<propertyName1>value</propertyName1>
<propertyName2>value</propertyName2>
<propertyName3>value</propertyName3>
...
</properties>
...
</project>
使用EL
表达式引用自定义属性:
<?xml version="1.0" encoding="UTF-8"?>
<project ... >
...
<properties>
<junit.junit.version>1.0.0</junit.junit.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<!-- 使用EL表达式引用 -->
<version>${junit.junit.version}</version>
</dependency>
</dependencies>
...
</project>
版本管理
对于大量依赖第三方构件的项目,可以将所有依赖或插件的版本号集中管理,避免修改困难。
<!-- 在properties标签中自定义版本号标签名 -->
<properties>
<!-- 推荐使用"groupId.artifactId.version"的形式命名标签 -->
<group1.project1.version>1.0</group1.project1.version>
<group2.project2.version>1.0</group1.project1.version>
</properties>
<dependencies>
<dependency>
<groupId>com.group1</groupId>
<artifactId>project1</artifactId>
<!-- 使用EL表达式引用properties标签中自定义的版本号标签名 -->
<version>${group1.project1.version}</version>
</dependency>
<dependency>
<groupId>com.group2</groupId>
<artifactId>project2</artifactId>
<!-- 使用EL表达式引用properties标签中自定义的版本号标签名 -->
<version>${group2.project2.version}</version>
</dependency>
</dependencies>
资源声明
Maven
默认工程下只有Java
源码文件,可以使用pom.xml
指定需要编译的资源文件。
<!-- 在build标签下新建resources标签 -->
<build>
...
<resources>
<resource>
<!-- 指定资源路径 -->
<directory>...</directory>
<includes>
<!-- 指定包含的文件或子路径:
可以是确切的文件名 - 例"mapper/mapper.xml";
可以是子路径 - 例"mapper";
可以指定一类文件 - 例"**/*.xml"("**"表示任意级目录,"*"表示任意文件名) -->
<include>...</include>
...
</includes>
<!-- 指定排除的文件或子路径 -->
<excludes>
<!-- 指定包含的文件或子路径:
可以是确切的文件名 - 例"mapper/mapper.xml";
可以是子路径 - 例"mapper";
可以指定一类文件 - 例"**/*.xml"("**"表示任意级目录,"*"表示任意文件名) -->
<exclude>...</exclude>
...
</excludes>
<!-- 指定被声明的资源文件是否解析${...}中的内容 -->
<filtering>true</filtering>
<!-- 指定打包后资源文件在打包中的路径(根目录为target/classes) -->
<targetPath>...</targetPath>
...
</resource>
...
</resources>
...
</build>
示例:
<build>
<resources>
<resource>
<!-- 编译src/main/java下的指定文件 -->
<directory>src/main/java</directory>
<!-- 编译所有的.xml文件和.properties文件 -->
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
<!-- 指定被声明的资源文件是否解析${...}中的内容 -->
<filtering>true</filtering>
<!-- 将指定资源文件打包至target/classes/test下 -->
<targetPath>test</targetPath>
</resource>
<resource>
<!-- 编译src/main/resources下的所有文件 -->
<directory>src/main/resources</directory>
<!-- 是否开启过滤器 -->
<filtering>true</filtering>
<!-- 将指定资源文件打包至target/classes/test下 -->
<targetPath>test</targetPath>
</resource>
</resources>
</build>
被声明后的资源文件可以使用EL
表达式引用对应pom.xml
中定义的属性:
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project ... >
...
<properties>
<!-- 定义属性 -->
<jdbc.url>jdbc:mysql://localhost:3306/test</jdbc.url>
</properties>
...
<build>
<resources>
<resource>
<!-- 编译src/main/java下的指定文件 -->
<directory>src/main/java</directory>
<!-- 编译所有的.properties文件 -->
<includes>
<include>**/*.properties</include>
</includes>
<!-- 指定被声明的资源文件是否解析${...}中的内容,
如果设置为false,配置文件将不能解析${...}中的属性值 -->
<filtering>true</filtering>
</resource>
</resources>
</build>
...
</project>
配置文件使用EL
表达式引用属性:
jdbc.properties
driver=com.mysql.jdbc.driver
# 使用EL表达式引用指定属性
url=${jdbc.url}
username=root
password=123456
项目打包
项目上线时需要对项目进行打包操作,普通Java
项目打包为jar
格式,JavaWeb
项目打包为war
格式。使用pom.xml
可以很方便地实现打包相关的配置。
<?xml version="1.0" encoding="UTF-8"?>
<project ... >
...
<groupId>com.oner</groupId>
<artifactId>dao</artifactId>
<version>1.0-SNAPSHOT</version>
...
<!-- packaging标签指定打包类型:
jar - Java压缩包,适用于普通Java项目,默认值
war - Web压缩包,适用于JavaWeb项目 -->
<packaging>war</packaging>
...
</project>
环境管理
多环境配置
实际开发项目时会在多种环境下运行项目,例如开发项目时需要使用开发环境,项目上线时需要使用实际的生产环境。Maven
可以管理多种环境,并在运行时运行指定的环境。
<?xml version="1.0" encoding="UTF-8"?>
<project ... >
...
<!-- 使用profiles标签管理多个环境 -->
<profiles>
<!-- 开发环境 -->
<profile>
<!-- id指定环境的唯一标识 -->
<id>develop</id>
</profile>
<!-- 生产环境 -->
<profile>
<id>product</id>
</profile>
...
</profiles>
...
</project>
默认环境
可以指定某个环境为默认环境,不带参数运行项目时将使用默认环境。
<?xml version="1.0" encoding="UTF-8"?>
<project ... >
...
<!-- 使用profiles标签管理多个环境 -->
<profiles>
<!-- 开发环境 -->
<profile>
<!-- id指定环境的唯一标识 -->
<id>develop</id>
<!-- 在activation标签中配置 -->
<activation>
<!-- 指定环境为默认环境 -->
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<!-- 生产环境 -->
<profile>
<id>product</id>
</profile>
...
</profiles>
...
</project>
环境参数
可以在环境中定义属性参数,使用此环境时可以供其它文件使用环境中的参数:
<profiles>
<profile>
<id>develop</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<!-- 自定义属性 -->
<properties>
<jdbc.url>jdbc:mysql://localhost:3306/test</jdbc.url>
</properties>
</profile>
<profile>
<id>product</id>
<!-- 自定义属性 -->
<properties>
<jdbc.url>jdbc:mysql://oner.com/users</jdbc.url>
</properties>
</profile>
</profiles>
使用EL
表达式引用属性:
jdbc.properties
driver=com.mysql.jdbc.driver
# 使用EL表达式引用指定属性
url=${jdbc.url}
username=root
password=123456
环境指令
通过Maven
指令运行工程时,如果Maven
指令不带参数,将使用默认环境运行。如果需要运行指定环境,可以为对应的Maven
指令带上参数:
/* -P之后跟随指定环境的id值,"-P develop"指定使用id为"develop"的环境运行工程 */
install -P develop
/* "-D skipTests"参数用于指定运行时跳过所有测试环节 */
install -P develop -D skipTests