爬梯:Maven全解析
Maven
自动化构建工具
官网:https://maven.apache.org
1. Maven简介
Maven是Apache软件基金会组织维护的自动化构建工具,专注于服务Java平台的项目构建和依赖管理。
市面上的自动化构建工具还有:Ant、Gradle
自动化构建,将项目代码从源文件到打包好这段过程中的操作自动完成,不需要人为操作,节省时间提高工作效率。
构建项目的各个环节:
- 清理:删除以前的编译结果;
- 编译:将Java源文件编译为字节码文件;
- 测试:针对项目中的关键点进行测试;
- 报告:将每一次测试后的结果以标准格式记录和展示;
- 打包:将工程包装成一个压缩文件;
- 安装:将打包的结果(jar/war)安装到本地仓库;
- 部署:将打包的结果部署到远程仓库。
2. Maven的使用
2.1 安装Maven
官方下载地址:https://maven.apache.org/download.cgi
-
下载压缩包,解压到一个非中文无空格的目录下;
-
因为Maven是java开发的,所以运行需要jdk环境;
-
配置maven环境变量:
MAVEN_HOME: D:\apache-maven-3.6.1 path:...;%MAVEN_HOME%\bin
-
查看maven是否安装成功
C:\Users\84548>mvn -v Apache Maven 3.6.1 (d66c9c0b3152b2e69ee9bac180bb8fcc8e6af555; 2019-04-05T03:00:29+08:00) Maven home: D:\apache-maven-3.6.1\bin\.. Java version: 1.8.0_211, vendor: Oracle Corporation, runtime: D:\Java\JDK1.8.0_211\jre Default locale: zh_CN, platform encoding: GBK OS name: "windows 10", version: "10.0", arch: "amd64", family: "windows"
2.2 网络配置
Maven的核心程序并不包含具体功能,仅负责宏观调度(领导)。具体功能由插件完成。Maven核心程序会到本地仓库中查找插件。如果本地仓库中没有则从远程*仓库下载。(所以若当前没有广域网则无法使用Maven的具体功能)
因此,我们需要给Maven配置本地仓库。
-
Maven的默认本地仓库地址:${user.home}/.m2/repository
...\conf\settings.xml <!-- localRepository | The path to the local repository maven will use to store artifacts. | | Default: ${user.home}/.m2/repository <localRepository>/path/to/local/repo</localRepository> -->
-
添加localRepository属性
<localRepository>D:\m2\repository</localRepository>
D:\m2\repository 是我本地放jar包的目录
至此,本地仓库就配置完了。
2.3 Hello Maven
编写一个Maven程序
-
创建约定的目录结构:
HelloMaven 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"> <modelVersion>4.0.0</modelVersion> <groupId>com.ssx.maven</groupId> <artifactId>HelloMaven</artifactId> <version>1.0-SNAPSHOT</version> <name>HelloMaven</name> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.0</version> <scope>test</scope> </dependency> </dependencies> </project>
-
编写主程序
src/main/java/com/ssx/maven/HelloMaven.java
package com.ssx.maven; public class HelloMaven{ public String say(String name){ return "Hello "+name; } }
-
编写测试代码
/src/test/java/com/ssx/maven
package com.ssx.maven; import org.junit.Test; public class TestHello{ @Test public void testHello(){ HelloMaven hello = new HelloMaven(); String result = hello.say("爸爸"); System.out.pintln(result); } }
-
使用maven构建HelloMaven项目
#1. 编译 ...\HelloMaven>mvn compile ...\HelloMaven>mvn test-compile ...\HelloMaven>mvn test #2. 测试 ------------------------------------------------------- T E S T S ------------------------------------------------------- Running com.ssx.maven.TestHello Hello 鐖哥埜 Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.055 sec Results : Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 #3.打包 ...\HelloMaven>mvn package #4.安装到仓库 ...\HelloMaven>mvn install
3. Maven核心概念
Maven实现自动化构建的原理:
3.1 Pom
- Project object module,项目对象模型;
- maven将项目当成模型来管理,通过pom.xml控制项目的构建过程;
3.2 约定的目录结构
maven项目的目录和文件的位置都是规定的;
3.3 坐标
唯一的字符串,用来表示资源;
- groupId:公司或组织的域名倒序+当前项目名称;
- artfactId:当前项目的模块名称;
- version:当前模块的版本;
- 仓库中的坐标:com/ssx/maven/Hello/0.0.1-SNAPSHOT/HelloMaven-0.0.1-SHAPSHOT.jar
3.4 依赖管理
管理项目可以使用的jar文件;
3.4.1 依赖范围
compile | test | provided | |
---|---|---|---|
main 目录下的Java代码可以访问 | 是 | 否 | 是 |
test 目录下的Java代码可以访问 | 是 | 是 | 是 |
是否参与打包 | 是 | 否 | 否 |
是否参与部署 | 是 | 否 | 否 |
- 其它
- runtime
- import
- system
3.4.2 依赖的传递性
间接依赖时,只有依赖范围是compile时才可以访问;
3.4.3 依赖的原则
- 路径最短优先
- 先声明优先(dependency的先后顺序)
3.4.4 依赖的排除
当引入的jar包内部还有jar包,并且会与主项目、其它jar冲突时,为了确保引用的是需要的那个jar包,可以使用exclusion指定排除。
<!-- 引入HelloMaven包,但是排除里面的commons-logging -->
<dependency>
<groupId>com.ssx.maven</groupId>
<artifactId>HelloMaven</artifactId>
<version>0.0.1-SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.2</version>
</dependency>
3.4.5 统一管理目标jar包的版本
以对Spring的jar包依赖为例:Spring的每一个版本中都包含sprin-sore、spring-context等jar包。我们应该统一导入版本一致的Spring jar包,而不是使用哦4.0.0的spring-core的同时使用4.1.1的spring-context。
<properties>
<spring.version>4.1.1.RELEASE</spring.version>
</properties>
<dependencys>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
</dependencys>
3.5 仓库
- 分类
- 本地仓库
- 远程仓库
- 私服:架设在局域网环境内;
- *仓库:架设在公网上;
- *仓库镜像:架设在各大洲,为*仓库分担流量;
- 文件
- Maven插件;
- 自己开发的项目模块;
- 第三方架构或工具的jar包;
3.6 生命周期
- Maven定义了各个构建环节的执行顺序,指定三套相互独立的生命周期:
- Clean Lifecycle:在进行真正的构建之前进行一些清理工作;
- pre-clean:执行清理之前的工作;
- clean:移除所有上一次构建生成的文件;
- post-clean:执行清理之后的工作;
- Default Lifecycle:构建的核心部分:编译、测试、打包、安装、部署等;
- Site Lifecycle:生成项目报告、站点、发布站点;
- pre-site:执行生成站点文档之前的工作;
- site:生成项目的站点文档;
- post-site:执行生成站点文档之后的工作,并为部署做准备;
- site-deploy:将生成的站点文档部署到特定的服务器上;
- Clean Lifecycle:在进行真正的构建之前进行一些清理工作;
3.7 插件和目标
- Maven的核心仅仅定义了抽象的生命周期,具体的任务都交由插件完成
- 每个插件都能实现多个功能,每个功能就是一个插件目标;
- Maven的生命周期与插件目标相互绑定,已完成某个具体的构建任务;
3.8 继承
例如junit包一般是使用test范围的,那么就不会被compile打包进来,然后如果需要统一junit包的版本就需要进去各个子项目修改,,,
使用继承可以很舒服的解决这个问题。
- 创建父工程,打包方式设为:pom
- 子工程中引入父工程
<parent>
<groupId></groupId>
<artifactId></artifactId>
<version></version>
<relativePath>当前目录到父工程的pom.xml文件的相对路径 </relativePath>
</parent>
如果子工程的groupId和version与父工程重复,则可以删除
- 父工程中管理依赖
<!-- 父工程 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!-- 子工程 不写范围和版本-->
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
</dependencies>
3.9 聚合
项目引用模块时,都是将模块打包jar之后安装入仓库,再从仓库引用到项目里。
聚合可以批量进行maven工程的安装、清理工作。
<!-- 主项目 -->
<modules>
<module></module>
<module></module>
</modules>
这样就可以直接引用目标模块,不需要单独打包再引入。
3.10 Maven常用设置
Maven的属性设置:
<properties>
<!-- maven构建项目使用编码 -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- 编译代码使用jdk版本 -->
<maven.compiler.source>1.8</maven.compiler.source>
<!-- 运行程序使用jdk版本 -->
<maven.compiler.target>UTF-8</maven.compiler.target>
<!-- 自定义变量,定义版本号 -->
<spring.version>4.1.1.RELEASE</spring.version>
</properties>
然后通过 ${属性名} 应用:
<dependencys>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
</dependencys>
3.11 插件
官方插件目录:https://maven.apache.org/plugins/index.html
maven编译插件:
<!-- 控制配置maven构建项目的参数设置、jdk版本 -->
<build>
<!-- 配置插件 -->
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<!-- jdk编译版本 -->
<source>1.8</source>
<!-- jdk运行版本 -->
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
资源设置:
<build>
<resources>
<resource>
<!-- 扫描资源的目录 -->
<directory>src/main/java</directory>
<includes><!-- 指定扫描规则 -->
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering><!-- 是否启用过滤器 -->
</resource>
</resources>
</build>
没有使用resources的时候(默认),maven执行编译代码时会把 src/main/resources 目录下的文件拷贝到 target/classes,对于 src/main/java 目录下的非java文件不处理。
5. IDEA整合Maven
5.1 Idea设置Maven
先这样
File —> Settings:设置当前项目
File —> Other Settings:设置未来的新项目
然后这样这样
Build,Execution,Deployment —> Build Tools —> Maven
配置运行项:
# maven构建项目的时候,会去*下载模版文件(7兆左右),指定internal则无需下载,提升创建maven项目的速度
-DarchetypeCatalog=internal
5.2 Idea创建Maven项目
- File -> new Project,选择空白项目
空白项目的名称
- 新建模块,选择maven
- 使用模版项目创建javase工程
输入模块信息
模块的maven配置
- 创建完成
5.3 Idea中的Maven窗口
idea右侧的标签有一项叫做 Maven,click it
这里可以直接双击操作maven。
5.4 Idea中操作Maven小技巧
5.4.1 某个module的依赖报错
选择对应pom.xml,右键刷新依赖
5.4.2 手动指定maven约定目录
maven的约定目录有时候会在idea中显示不出来,则可以手动指定。
指定java目录,测试java目录,源文件目录等等
设定的地方有两个:
上一篇: 爬梯:Git
下一篇: 爬梯:Redis全解析(二)