Maven 文件结构
目录 |
说明 |
bin |
Maven运行的脚本 |
boot |
包含plexus-classworlds-2.5.2.jar Maven的类加载框架 |
conf |
该目录包含一个非常重要的配置文件setting.xml。修改该文件就能全局的定制Maven的行为, 用户也可以在~/.m2/目录来建立用户范围级别的Maven行为配置 |
lib |
Maven运行时所需要的Java类库 |
LICENSE |
开源协议说明 |
NOTICE |
Maven 依赖第三方核心库的说明 |
README.txt |
Maven 介绍说明 |
Maven编译
约定(主代码)
默认情况下,Maven假设项目主代码位于 src/main/java目录,一般该目录会被打包到最终的构件中(如jar)
命令
命令 |
说明 |
clean |
清理输出目录 target/ |
resources |
处理资源文件 |
compile |
编译项目主代码 |
package |
项目打包 |
install |
将项目输出的jar安装到本地仓库中 |
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
|
<?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"> <modelVersion>4.0.0</modelVersion>
<groupId>com.cotide</groupId> <artifactId>MyProject</artifactId> <name>Default Project</name> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <classifier></classifier> </project>
|
节点 |
说明 |
name |
名称 - 设计目的方便阅读 (可选) |
groupId |
坐标 (定义唯一的项目或者组织) |
artifactId |
基于坐标的项目名称 |
version |
项目版本 |
packaging |
打包文件格式 pom, jar, maven-plugin, ejb, war, ear, rar, par |
格式:groupId:artifactId:version
格式: groupId:artifactId:packaging:classifier:version
POM依赖范围
类型 |
说明 |
compile |
编译依赖范围(默认) |
test |
测试依赖范围 |
provided |
已提供依赖范围 |
runtime |
运行时依赖范围 |
system |
系统依赖范围 |
import |
导入依赖范围 |
POM依赖关系
在POM配置中没有指定依赖范围默认为compile,当遇到A->B-C库的时候这种行为叫传递性依赖
例子:A -> B -> C-> X(1.0) 和 A -> D- >X(2.0)
1.路径最近者优先
例子:A -> B -> Y(1.0) 和 A -> C-> Y(2.0)
2.第一声明者优先
- 可选依赖
可以自行配置依赖选择方式,通过进行配置,标记该配置的的项目不会被传递依赖。
1 2 3 4
| # 依赖关系 A -> B -> mysql-connector-java (可选) A -> B -> postgresql (可选)
|
mysql-connector-java 和 postgresql 只会对项目B产生影响,当A依赖B的时候,这两个依赖不会被传递,如果项目A想依赖需要显示的去声明mysql-connector-java 和 postgresql
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.10</version> <optional>true</optional> </dependency> <dependency> <groupId>postgresql</groupId> <artifactId>postgresql</artifactId> <version>8.4-701.jdbc3</version> <optional>true</optional> </dependency>
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.10</version> </dependency>
|
例如:项目依赖一个有版权问题的project-b的 jar,如果需要使用该项目,可以显示的去替换这个依赖关系
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <dependencies> <dependency> <groupId>com.juvenxu.mvnbook</groupId> <artifactId>project-b</artifactId> <version>1.0.0</version> <exclusions> <exclusion> <groupId>com.juvenxu.mvnbook</groupId> <artifactId>project-c</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>com.juvenxu.mvnbook</groupId> <artifactId>project-c</artifactId> <version>1.1.0</version> </dependency> </dependencies>
|
- 归类依赖
项目中如果依赖多个版本的JAR(构件),为了更方便的去升级该项目,可以使用该配置
1 2 3 4 5
| 业务场景:统一springframework的版本 思路: 1. 定义属性<属性名> 2. 使用占位符${属性名} 动态注入到<version> 配置项中
|
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
| <properties> <springframework.version>2.5.6</springframework.version> </properties>
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>${springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-suport</artifactId> <version>${springframework.version}</version> </dependency> </dependencies>
|
通过Intellij IDE 的Terminal工具可以很方便的去了解当前的依赖关系
1 2 3 4 5 6 7 8 9
| # 显示依赖关系 $ mvn dependency:list
# 显示层级关系依赖 $ mvn dependency:tree
# 依赖关系分析 $ mvn dependency:analyze
|
Maven 仓库
任何一个依赖,插件或者项目构建的输出,都称为构件。任何一个构件都有一组坐标唯一标识。任何Maven项目使用任何一个构件的方式都是完全相同的。在此基础上,Maven可以在某一个位置统一存储所有Maven项目共享的构件,这个统一的位置就是仓库
Maven仓库
Maven仓库 (AliYun镜像)
仓库分类
当Maven根据坐标需找构件的时候,首先会检查本地仓库是否存在构件,如果存在直接使用,如果不存在则去远程仓库查找并下载到本地仓库
自定义配置
配置级别
Windows
- 全局级别配置 Maven3.5\conf\settings.xml
- 用户级别配置 C:\Users\用户\settings.xml
Linux
- 全局级别配置 Maven3.5\conf\settings.xml
- 用户级别配置 ~/.m2/settings.xml
本地仓库配置
修改settings.xml 设置localRepository元素值为仓库本地地址
1 2 3 4
| <setting> <localRepository>F:\lib</localRepository> </setting>
|
远程仓库配置
修改settings.xml 设置mirror元素值为仓库远程地址
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
| <setting> <mirrors> <mirror> <id>nexus-aliyun</id> <mirrorOf>*</mirrorOf> <name>Nexus aliyun</name> <url>http://maven.aliyun.com/nexus/content/groups/public</url> </mirror> </mirrors> </setting>
```
#### 远程仓库认证配置
> 修改settings.xml 设置server元素认证信息
``` xml
<setting> <servers> <server> <id>my-proj</id> <username>repo-user</username> <password>repo-pwd</password> </server> </servers> </setting>
|
仓库快照配置
快照是一个特殊的版本,它表示当前开发的一个副本。与常规版本不同,Maven 为每一次构建从远程仓库中检出一份新的快照版本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <distributionManagement> <repository> <id>proj-releases</id> <name>Proj Release Repository</name> <url>远程仓位置</url> </repository> <snapshotRepository> <id>proj-snapshots</id> <name>Proj Snapshot Repository</name> <url>远程仓位置</url> </snapshotRepository> </distributionManagement>
|
1 2
| # 设置Maven 每次自动获取最新的快照 $ mvn clean package -U
|
生命周期和插件
Maven两个核心概念是生命周期和插件,Maven的生命周期是抽象的,其实际行为都由插件来完成,所以需要两者协同工作
生命周期
- clean 生命周期的目的是清理项目
- default 生命周期的母的是构建所需执行的所有步骤
- site 生命周期的目的是建立和发布项目信息
插件
获取 Apache Maven 官方插件
插件管理
Maven提供了pluginManagement元素帮助管理依赖,通过配置该元素来注入到Maven的生命周期中
聚合
目地为了方便快速构建项目
事例:项目需要同时编译输出两套构件,可以建立新的项目依赖两套构件,修改POM配置如下:
1 2 3 4 5 6
| <packaging>pom</packaging> <modules> <module>构件A</module> <module>构件B</module> </modules>
|
1 2
| # 执行命令 $ mvn clean install
|
继承
目地为了简化构件中重复POM配置
事例:
Parent项目 -> 构件A
Parent项目 -> 构件B
Parent项目的POM
1 2 3 4 5 6
| <project> <groupId>com.cotide</groupId> <artifactId>Parent项目</artifactId> <version>1.0.0</version> <packaging>pom</packaging> </project>
|
构件A的POM
1 2 3 4 5 6 7
| <parent> <groupId>com.cotide</groupId> <artifactId>Parent项目</artifactId> <version>1.0.0</version> <relativePath>Parent项目目录/pom.xml</relativePath> </parent>
|
构件B的POM
1 2 3 4 5 6 7
| <parent> <groupId>com.cotide</groupId> <artifactId>Parent项目</artifactId> <version>1.0.0</version> <relativePath>Parent项目目录/pom.xml</relativePath> </parent>
|
依赖管理
基于继承依赖,进行依赖管理
事例:
Parent项目 -> 构件A (引用构件C)
Parent项目 -> 构件B (引用构件C)
Parent项目的POM
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <project> <groupId>com.cotide</groupId> <artifactId>Parent项目</artifactId> <version>1.0.0</version> <packaging>pom</packaging> <dependencyManagement> <dependencies> <dependency> <groupId>构件C groupId</groupId> <artifactId>构件C</artifactId> <version>1.0.0</version> </dependency> </dependencies> </dependencyManagement> </project>
|
构件A的POM
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <parent> <groupId>com.cotide</groupId> <artifactId>Parent项目</artifactId> <version>1.0.0</version> <relativePath>Parent项目目录/pom.xml</relativePath> </parent> <dependencies> <dependency> <groupId>构件C groupId</groupId> <artifactId>构件C</artifactId> </dependency> </dependencies>
|
构件B的POM
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <parent> <groupId>com.cotide</groupId> <artifactId>Parent项目</artifactId> <version>1.0.0</version> <relativePath>Parent项目目录/pom.xml</relativePath> </parent> <dependencies> <dependency> <groupId>构件C groupId</groupId> <artifactId>构件C</artifactId> </dependency> </dependencies>
|
IntelliJ IDEA 实战 - 添加junit项目
创建项目 (Maven结构)
编辑POM
项目pom.xml 文件结构如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <?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"> <modelVersion>4.0.0</modelVersion> <groupId>com.cotide.core</groupId> <artifactId>framework</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> </dependencies> </project>
|
关于 接点的依赖关系可以通过查询Maven官方中央仓http://search.maven.org 找到对应的pom配置,由于国内线路访问国外线路慢的问题可以查询阿里Maven镜像http://maven.aliyun.com/nexus
Intellij IDEA 默认自带Maven,如果需要修改自己的配置需要在File -> Settings -> Maven 上进行Maven 配置
运行Maven
选择Run -> Edit Configurations 添加Maven 编译配置 -> 点击Run 执行
执行完后,在项目下已经添加了junit的依赖,并生成target目录下的文件
Maven 输出乱码问题
pom.xml 配置如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.20</version> <configuration> <forkMode>once</forkMode> <argLine>-Dfile.encoding=UTF-8</argLine> </configuration> </plugin> </plugins> </build>
|
Maven 打包控制台项目
pom.xml 配置如下:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.cotide.main</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
扩展
Nexus
Maven仓库管理软件, Nexus分为开源版和专业版,其开源版本基于CPLv3 许可证
Nexus 搭建
http://books.sonatype.com/nexus-book/3.0/reference/install.html
持续集成
自动化部署
Maven Archetype
Archtype是项目的骨架,通过Maven中的maven-archetype-plugin插件用户可以快速的去生成所需的项目骨架.
# 构建generate项目骨架
$ mvn archetype:generate
参考资料