一、Maven简介
(一)什么是Maven
Maven 是 Apache 软件基金会组织维护的一款自动化构建工具,专注服务于 Java 平台的项目构建和依赖管理,可以管理项目生命周期中的构建(编译、运行测试、打包、部署等)和项目的依赖(jar包) ,以及管理项目各个模块之间的依赖关系。Maven 这个单词的本意是:专家,内行。
(二)为什么使用Maven
1、Maven能提供一种项目的配置。配置好的项目,只需要运行一条简单的命令,就能完成重复的、繁琐的构建动作。
2、Maven能提供一种项目的依赖配置。可以自动的导入项目依赖的jar,并且自动导入这些jar包依赖的第三方的jar包。
3、Maven提供了一种标准的项目目录结构,测试命名规则等项目的最佳实践方案,减少了不同项目的学习成本。
4、使用Maven可以将一个庞大的项目拆分成多个工程模块,便于开发和维护。
二、Maven下载和安装
(一)下载
1、下载最新版本
http://maven.apache.org/download.cgi 下载最新版本
2、下载历史版本
https://archive.apache.org/dist/maven/maven-3/
(二)安装
解压即可,无需安装。不要解压要带有中文或特殊字符的目录中。
bin:存放执行脚本文件的地方。
boot:存放一些扩展的地方,类加载的文件。
conf:maven的核心配置文件存放的路径。
lib:maven的依赖包。
(三)环境变量配置
1、前提
要使用Maven必须保证jdk安装正确(Maven3.3以上版本要求jdk1.7及以上版本)。保证JAVA_HOME配置正确。
2、配置环境变量
新建环境变量MAVEN_HOME,指向maven的根目录
(四)验证Maven安装
打开cmd窗口,敲入mvn –v 查看
三、Maven的配置
(一)Maven仓库
(二)配置本地仓库
在Maven安装路径下,conf文件夹中,修改settings.xml配置文件。
配置localRepository标签的值。
<localRepository>本地磁盘路径</localRepository>
(三)Maven配置远程仓库镜像
Maven默认远程仓库是中央仓库,地址为:https://repo.maven.apache.org/maven2
Maven默认的远程仓库,受网络的影响,不够便捷。于是可以使用国内的阿里云的Maven仓库作为中央仓库的镜像。配置方式可以在settings.xml的配置文件中配置mirrors标签
<mirror>
<id>mirrorId</id>
<mirrorOf>central</mirrorOf>
<name>Human Readable Name for this Mirror.</name>
<url>https://maven.aliyun.com/nexus/content/groups/public/</url>
</mirror>
id:当前镜像的唯一的标识
name:当前镜像的名字,主要方便于开发者阅读。
mirrorOf:为哪个远程仓库做的镜像。因为中央仓库的id为central,所以为中央仓库做镜像时,其值必须为”central” 。
url:阿里云Maven仓库的地址。
(四)配置JDK版本
Maven创建的项目默认的JDK版本是1.5,可以在setting.xml中修改
<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>
</properties>
</profile>
四、Maven入门案例
(一)Maven项目的目录结构说明
Maven规定了一套标准的目录结构:
src/main/java —— 存放项目的.java文件
src/main/resources —— 存放项目资源文件,如db.properties配置文件,
src/main/webapp —— 存放jsp、css、image等文件(java项目不包含此目录)
src/test/java —— 存放所有测试.java文件,如JUnit测试类
src/test/resources —— 测试资源文件
pom.xml——maven配置文件
target —— maven自动输出位置
(二)开发步骤
1、按照下面的目录结构创建一个目录结构
HelloMaven
--src
-----main
----------java
-----test
----------java
--pom.xml
2、在src/main/java下添加类
package com.offcn.maven;
public class Hello {
public String sayHello(String name){
return "Hello "+name;
}
}
3、在src/test/java下添加类
package com.offcn.maven;
import org.junit.Test;
public class HelloTest {
@Test
public void testHello(){
Hello hello = new Hello();
String results = hello.sayHello("World");
System.out.println("Hello World".equals(results));
}
}
4、编辑pom.xml
https://mvnrepsitory.com
<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.offcn.maven</groupId>
<artifactId>Hello</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Hello</name>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
5、运行命令窗口,分别执行下列命
执行 mvn compile命令:编译项目
执行mvn clean命令:清除字节码
执行mvn test命令:执行测试
执行mvn package命令:项目的打包。java项目-jar Web项目-war
执行mvn install命令:将项目打成的包安装到maven本地仓库中
五、IDEA中配置Maven
(一)IDEA关联Maven
点击File中的Settings,选择Build,Execution,Deployment--->Maven,配置Maven home directory和User settings file,使Idea与Maven关联
Maven home directory:
可以指定本地 Maven 的安装目录所在。这里不建议使用 IDEA 默认的。
User settings file / Local repository:
我们还可以指定 Maven 的 settings.xml 位置和本地仓库位置。
Import Maven projects automatically:
表示 IntelliJ IDEA 会实时监控项目的pom.xml 文件,进行项目变动设置。
Automatically download:
在 Maven导入依赖包的时候是否自动下载源码和文档。默认是没有勾选的,也不建议勾选,原因是这样可以加快项目从外网导入依赖包的速度。如果我们需要源码和文档的时候我们到时候再针对某个依赖包进行联网下载即可。IntelliJ IDEA支持直接从公网下载源码和文档的。
VM options for importer:
可以设置导入的 VM 参数。一般这个都不需要主动改,除非项目真的导入太慢了,我们再增大此参数。
(二)创建Maven项目
创建项目时,选择左侧的Maven,之后可以直接next,录入项目的坐标之后,可以直接创建出默认的Java项目。如果需要创建web项目,最优方式是勾选“Create from archetype”选项,选择“maven-archetype-webapp”进行创建。
点击下一步,录入项目名和坐标:
groupId,artifactId,version的录入原则:
groupId翻译为组Id,通常的写法为公司域名的倒写,表示本项目属于哪个公司。
artifactId翻译为手工艺品,表示项目的的名字或者模块的名字。
Version通常为X.X.X格式,表示项目的版本号。
点击finsh即可创建好maven项目。
(三)Maven的目录结构图标
IDEA中,不同的目录结构,使用不同图标进行标识,IDEA中的图标示例为:
因此,创建出的项目需要补全文件夹时,除了需要创建对应的文件夹之外,还需要对文件夹进行不同角色的标记。
(四)运行Maven命令
首先,打开Maven的视图窗口。选择View--->Tool Windows--->Maven Projects
或者可以手动执行命令
五、依赖和插件管理
(一)依赖管理
1、添加Maven依赖
在项目的pom.xml文件中,添加<dependencies>标签,在标签中的每个依赖需要对应<dependency>标签,<dependency>标签中需要填写jar包坐标。
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.23</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.9</version>
</dependency>
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
</dependencies>
当不清楚如何填写某个jar包的坐标时,给大家推荐一种方式。访问:
https://mvnrepository.com/ 进行搜索
2、Maven的依赖范围
依赖:项目需要依靠一个jar
依赖范围:依赖一个jar,并不一定是在项目整个生命周期都需要它,可能只是在某一个阶段需要,那么依赖范围就是定义在哪些阶段依赖这个jar
A依赖B,需要在A的pom.xml文件中添加B的坐标。
scope:是依赖的范围。
scope有几个可选值,如:
1、compile: 默认值,表示编译依赖范围。即编译、测试、运行时都需要,会被打包。(默认值compile表明该jar一直全程存在/需要)
2、test:表示测试依赖范围。即测试时需要,编译和运行时不需要,不会被打包。比如:junit。
3、provided:表示已提供依赖范围。即编译、测试时需要,运行时不需要,不会被打包。比如:servlet-api和jsp-api由Tomcat容器提供。
服务器本身会提供这些jar,避免和服务器上的这些包冲突
4、runtime:表示运行时提供依赖范围。即编译时不需要,运行和测试时需要,会被打包。比如:JSTL、JDBC驱动。
5、system:system范围依赖与provided类似,但是你必须显式的提供一个对于本地系统中jar文件的路径,需要指定systemPath磁盘路径,system依赖不推荐使用。
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version>
<scope>test</scope>
</dependency>
3、依赖排除
如果我们在当前工程中引入了一个依赖是 A,而 A 又依赖了 B,那么 Maven 会自动将 A 依赖的 B 引入当前工程,但是个别情况下 B 有可能是一个不稳定版,或对当前工程有不良影响。这时我们可以在引入 A 的时候将 B 排除。
(二)插件管理
前面Maven除讲解了如果修改Maven使用的默认JDK版本。在setting.xml中进行修改,那么所有使用当前Maven的项目的JDK版本都相同。也可以在项目的pom.xml中使用插件的方式进行修改。
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
目前学习的知识,需要使用到插件的地方不多,在今后的学习中,会逐渐使用多种Maven插件来方便我们的开发。
六、项目管理
(一)统一版本配置
统一管理所依赖 jar 包的版本,在开发中对同一个框架的一组 jar 包最好使用相同的版本。不同版本的jar包之间存在很大冲突,为了方便升级框架,可以将 jar 包的版本信息统一提取出来,进行统一的管理。
1、统一声明版本号
<properties>
<offcn.Spring.version>5.3.4</offcn.Spring.version>
</properties>
其中 offcn.Spring.version 部分是自定义标签
2、引用前面声明的版本号
<dependencies>
<dependency>
<groupId>org.Springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${offcn.Spring.version}</version>
</dependency>
<dependency>
<groupId>org.Springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${offcn.Spring.version}</version>
</dependency>
……
</dependencies>
(二)Maven项目的继承
1、继承应用
开发中,项目的结构较复杂需要拆分成多个单独的子项目时,由于所有的子项目同属于同一个项目,因此可能需要使子项目使用同一个版本的依赖。那么到各个工程中手动单独维护无疑是非常不可取的。使用继承机制可以将这样的依赖信息统一提取到父工程模块中进行统一管理。
配置为方式为:父项目创建Maven项目的打包方式为pom。
子项目中pom文件中,添加如下代码:
<parent>
<!--父工程坐标-->
<groupId>...</groupId>
<artifactId>...</artifactId>
<version>...</version>
</parent>
<parent>
<groupId>com.offcn.Maven</groupId>
<artifactId>Parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<!-- 指定从当前子工程的pom.xml文件出发,查找父工程的pom.xml的路径 -->
</parent>
2、dependencyManagement使用
我们之前用dependencies来声明依赖时,即使在子项目中不写该依赖项,子项目仍然会从父项目中继承该依赖项(全部继承)
dependencyManagement里只是声明依赖,并不实现引入,因此子项目需要显示的声明需要用的依赖。如果不在子项目中声明依赖,是不会从父项目中继承下来的;只有在子项目中写了该依赖项,并且没有指定具体版本,才会从父项目中继承该项,并且version和scope都读取自父pom;另外如果子项目中指定了版本号,那么会使用子项目中指定的jar版本。
父项目声明依赖,用<dependencyManagement>包围了<dependencies>
<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>
(三)Maven项目的聚合
将多个工程拆分为模块后,需要手动逐个安装到仓库后依赖才能够生效。修改源码后也需要逐个手动进行 clean 操作。而使用了聚合之后就可以批量进行 Maven 工程的安装、清理工作。
在总的聚合工程中使用 modules/module 标签组合,指定模块工程的相对路径即可
<modules>
<module>../mu1</module>
<module>../mu2</module>
<module>../mu3</module>
</modules>