Maven
Maven 概述
类似自动化构建工具还有:Ant、Maven、Gradle。
如果包与包之间不兼容的话 Maven 会报错,在 IDEA 中会有红色的波浪线。
完成一个 java 项目需要做的工作
1、分析项目要做什么,知道项目有哪些组成部分。
2、设计项目,通过哪些步骤,使用哪些技术。需要多少人, 多长的时间。
3、组建团队,招人, 购置设备,服务器, 软件, 笔记本。
4、开发人员写代码。 开发人员需要测试自己写代码。 重复多次的工作。
5、测试人员,测试项目功能是否符合要求。
- 流程:
测试开发人员提交代码;如果测试有问题;需要开发人员修改;在提交代码给测试;测试人员在测试代码;如果还有问题;在交给开发人员;开发人员在提交;再测试;直到测试代码通过。
传统开发项目的问题
1、很多模块,模块之间有关系, 手工管理关系,比较繁琐。
2、需要很多第三方功能, 需要很多 jar 文件,需要手工从网络中获取各个 jar。
3、需要管理 jar 的版本,比如:需要的是 mysql.5.1.5.jar,mysql.4.0.jar 就不对。
4、管理jar文件之间的依赖,项目要使用 a.jar 需要使用 b.jar 里面的类。必须首先获取到 b.jar 才可以, 然后才能使用 a.jar。
- 例子:
a.jar需要b.jar这个关系叫做依赖, 或者你的项目中要使用mysql的驱动, 也可以叫做项目依赖mysql驱动。
a.class使用b.class, a依赖b类
用 maven 改进项目的开发和管理
1、maven 可以管理 jar 文件。
2、自动下载 jar 和他的文档,源代码。
3、管理jar直接的依赖, a.jar 需要 b.jar,maven 会自动下载 b.jar。
4、管理需要的 jar 版本。
5、编译程序,把 java 编译为 class。
6、测试你的代码是否正确。
7、打包文件,形成 jar 文件,或者 war 文件。
8、部署项目。
Maven 的构建
构建是面向过程的,完成项目代码的编译,测试,运行,打包,部署等等。
- maven 支持的构建包括有:
1、清理, 把之前项目编译的东西删除掉,为新的编译代码做准备。
2、编译, 把程序源代码编译为执行代码, java-class文件。
批量的,maven可以同时把成千上百的文件编译为class。
javac 不一样,javac一次编译一个文件。
3、测试, maven可以执行测试程序代码,验证你的功能是否正确。
批量的,maven同时执行多个测试代码,同时测试很多功能。
4、报告, 生成测试结果的文件, 测试通过没有。
5、打包, 把你的项目中所有的class文件,配置文件等所有资源放到一个压缩文件中。
这个压缩文件就是项目的结果文件, 通常java程序,压缩文件是jar扩展名的。
对于web应用,压缩文件扩展名是.war。
6、安装, 把5中生成的文件 jar,war 安装到本机仓库。
7、部署, 把程序安装好可以执行。
maven 核心概念
1、POM:
文件名称是 pom.xml,pom 叫做项目对象模型(Project Object Module)。 maven 把一个项目当做一个模型使用。控制 maven 构建项目的过程,管理 jar 依赖。
2、约定的目录结构
maven 项目的目录和文件的位置都是规定的(约定是大家都遵循的一个规则)。
例子:每一个 maven 项目在磁盘中都是一个文件夹(项目-Demo)
Demo/
---/src
------/main #放你主程序java代码和配置文件
----------/java #你的程序包和包中的java文件
----------/resources #你的java程序中要使用的配置文件
------/test #放测试程序代码和文件的(可以没有)
----------/java #测试程序包和包中的java文件
----------/resources #测试java程序中要使用的配置文件
------/target #编译后存放 class 文件的目录
---/pom.xml #maven的核心文件(maven项目必须有)
命令:mvn compile
(编译 src/main 目录下的所有 java 文件)。执行后会进行 jar 文件的下载。
- 解释
1、为什么要下载?
maven 工具执行的操作需要很多插件(java 类--jar 文件)来完成。
2、下载了什么东西?
jar 文件(插件:插件是完成某些功能)。
3、下载的东西存放到哪里?
默认仓库(本机仓库):C:\Users\(登录操作系统的用户名)Administrator\.m2\repository
4、其中一个下载内容
Downloading: https://repo.maven.apache.org/maven2/org/apache/maven/maven-plugin-parameter-documenter-2.0.9.pom
https://repo.maven.apache.org:中央仓库的地址。
执行 mvn compile 之后,结果是在项目的根目录下生成 target 目录(结果目录),maven 编译的 class 文件都放在 target 目录中。
3、坐标 : 是一个唯一的字符串,用来表示资源的。
唯一值,在互联网中唯一标识一个项目的。
<groupId>公司域名的倒写</groupId>
<artifactId>自定义项目名称</artifactId>
<version>自定版本号</version>
groupId 、 artifactId 、 version 三个元素构成坐标。
groupId
组织 id,一般是公司域名的倒写。格式可以为:
1、域名倒写。 例如 com.baidu
2、域名倒写+项目名。例如 com.baidu.appolo
artifactId
项目名称,也是模块名称,对应 groupId 中项目中的子项目。
生成了一个 Maven 项目的基本坐标,在众多的 maven 项目中可以唯一定位到某一 个项目。坐标也决定着将来项目在仓库中的路径及名称。
version
项目的版本号。如果项目还在开发中,是不稳定版本, 通常在版本后带-SNAPSHOT
version 使用三位数字标识,例如:1.1.0。
- packaging
打包后压缩文件的扩展名,默认是 jar ,web 应用是 war。
packaging 可以不写, 默认是 jar。
4、依赖管理 : 管理你的项目可以使用jar文件
dependencies 和 dependency,相当于是 java 代码中 import。
是项目中要使用的各种资源说明,比如项目要使用 mysql 驱动:
<dependencies>
<!--依赖 java代码中 import -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.9</version>
</dependency>
</dependencies>
5、仓库管理(了解) :你的资源存放的位置
6、生命周期 (了解) : maven工具构建项目的过程,就是生命周期。
7、插件和目标(了解):执行maven构建的时候用的工具是插件
8、继承
9、聚合
maven 的使用需要用到命令,但在 idea 中直接使用 maven 会代替命令。
properties
<properties>
设置 maven 的常用属性。
<properties>
<!-- maven 构建项目使用编码,避免中文乱码 -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- 告诉 maven 在 jdk1.8 上编译 -->
<maven.compiler.source>1.8</maven.compiler.source>
<!-- 在 jdk1.8 上运行 -->
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
build
maven 在进行项目的构建时, 配置信息,例如指定编译 java 代码使用的 jdk 的版本等。
maven工具的安装和配置。
1、需要从 maven 的官网下载 maven 的安装包,如:apache-maven-3.8.1-bin.zip。
2、解压安装包,解压到一个目录(非中文目录)。
子目录 bin:执行程序,主要是 mvn.cmd;
conf:maven工具本身的配置文件 settings.xml;
3、配置环境变量
在系统的环境变量中,指定一个M2_HOME
的名称, 指定它的值是 maven 工具安装目录,bin 之前的目录:
M2_HOME=E:\javaResource\maven\apache-maven-3.8.1-bin\apache-maven-3.8.1
再把 M2_HOME 加入到 path 之中,在所有路径之前加入%M2_HOME%\bin;
4、验证,在新的命令行中,执行:mvn -v
注意:需要配置 JAVA_HOME ,指定 jdk 路径
C:\WINDOWS\system32>mvn -v
出现如下内容,maven安装,配置正确。
Apache Maven 3.8.1 (05c21c65bdfed0f71a2f2ada8b84da59348c4c5d)
Maven home: E:\javaResource\maven\apache-maven-3.8.1-bin\apache-maven-3.8.1\bin\..
Java version: 1.8.0_271, vendor: Oracle Corporation, runtime: E:\JDK1.8\jdk_1.8\jre
Default locale: zh_CN, platform encoding: GBK
OS name: "windows 10", version: "10.0", arch: "amd64", family: "windows"
设置本机仓库
设置本机存放资源的目录位置(设置本机仓库):
1、修改 maven 的配置文件,位置在:maven安装目录/conf/settings.xml。先备份 settings.xml。
2、修改 <localRepository>
并指定目录(不要使用中文目录)。先将<localRepository>
复制到外面,再将其改成自定义路径。
<!-- 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>E:/maven_repository</localRepository>
仓库
仓库是什么
1、仓库是存放东西的,存放 maven 使用的 jar 和项目使用的 jar(第三方的工具)。
2、https://mvnrepository.com
是 Maven 的中央仓库。
仓库的分类
本地仓库,就是个人计算机上的文件夹,存放各种 jar。
远程仓库,在互联网上的,使用网络才能使用的仓库。
①:中央仓库,最权威的, 所有的开发人员都共享使用的一个集中的仓库。:中央仓库的地址:https://repo.maven.apache.org
②:中央仓库的镜像:就是中央仓库的备份,在各大洲,重要的城市都是镜像。
③:私服,在公司内部,在局域网中使用的,不是对外使用的。
仓库的使用
maven 仓库的使用不需要人为参与。如:
开发人员需要使用 mysql 驱动,maven会首先查本地仓库;再到私服;再到镜像;最后到中央仓库去查找。
maven 的生命周期
1、maven 的生命周期:就是maven构建项目的过程,清理,编译,测试,报告,打包,安装,部署。
2、对项目的构建是建立在生命周期模型上的,它明确定义项目生命周期各个阶段,并且对于每一个阶段提供相 对应的命令,对开发者而言仅仅需要掌握一小堆的命令就可以完成项目各个阶段的构建工作。
3、构建项目时按照生命周期顺序构建,每一个阶段都有特定的插件来完成。不论现在要执行生命周期中的哪个 阶段,都是从这个生命周期的最初阶段开始的。
4、对于我们程序员而言,无论我们要进行哪个阶段的构建,直接执行相应的命令即可,无需担心它前边阶段是 否构建,Maven 都会自动构建。这也就是 Maven 这种自动化构建工具给我们带来的好处。
maven 的命令
概述
1、maven 独立使用,通过命令,完成maven的生命周期的执行。
2、maven 可以使用命令,完成项目的清理,编译,测试等等。
3、Maven 对所有的功能都提供相对应的命令,maven 三大功能:管理依赖、构建项目、管理项目信息。管理依赖,只需要声明就可以自动到仓库下载;管理项目信息其实就是生成一个站点文档,一个命令就可以解决,maven 功能的主体其实就是项目构建。
4、Maven 提供一个项目构建的模型,把编译、测试、打包、部署等都对应成一个个的生命周期阶段,并对 每一个阶段提供相应的命令,程序员只需要掌握一小堆命令,就可以完成项目的构建过程。
命令
mvn clean
:清理(会删除原来编译和测试的目录,即 target 目录,但是已经 install 到仓库里的包不会删除)。
mvn compile
:编译主程序(会在当前目录下生成一个 target,里边存放编译主程序之后生成的字节码文件)。
mvn test-compile
:编译测试程序(会在当前目录下生成一个 target,里边存放编译测试程序之后生成的字节码文件) 。mvn test
:测试(会生成一个目录surefire-reports,保存测试结果)。
mvn package
:打包主程序(会编译、编译测试、测试、并且按照 pom.xml 配置把主程序打包生成 jar 包或者 war 包) 。生成的是 src/main 下的所有内容(class文件)。
mvn install
:安装主程序(会把本工程打包,并且按照本工程的坐标保存到本地仓库中)。
<groupId>com.bjpwoernode.maven</groupId>
<artifactId>ch01-maven</artifactId>
<version>1.0-SNAPSHOT</version>
mvn deploy
:部署主程序(会把本工程打包,按照本工程的坐标保存到本地库中,并且还会保存到私服仓库中。 还会自动把项目部署到 web 容器中)。
注意:执行以上命令必须在命令行进入 pom.xml 所在目录!
maven 的插件
1、maven 过程构建周期,由 maven 的插件 plugin 来执行完成。
2、maven 命令执行时,真正完成功能的是插件,插件就是一些 jar 文件,一些类。
3、插件可以在自己的项目中设置,最常使用的是 maven 编译插件。设置项目使用的 jdk 版本时通过编译插件指定。在pom.xml 文件<build>
中设置。
<!-- 控制/配置 maven 构建项目的参数设置,设置 jdk 版本 -->
<build>
<!-- 配置插件 -->
<plugins>
<!-- 配置具体的插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<!-- 插件的名称 -->
<artifactId>maven-compiler-plugin</artifactId>
<!-- 插件的版本 -->
<version>3.8.1</version>
<!-- 配置插件的信息 -->
<configuration>
<!-- 告诉 maven 在 jdk1.8 上编译 -->
<source>1.8</source>
<!-- 在 jdk1.8 上运行 -->
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
插件说明
- clean 插件:maven-clean-plugin:2.5
clean 阶段是独立的一个阶段,功能就是清除工程目前下的 target 目录。 - resources 插件:maven-resources-plugin:2.6
resource 插件的功能就是把项目需要的配置文件拷贝到指定的目当,默认是拷贝 src\main\resources 目录下的件到 classes 目录下。 - compile 插件:maven-compiler-plugin
compile 插件执行时先调用 resouces 插件,功能就是把 src\main\java 源码编译成字节码生成 class 文件,并把编译好的 class 文件输出到 target\classes 目录下;把 main/resources 目录下的所有文件都拷贝到 target/classes 目录下。 - test 测试插件
单元测试所用的 compile 和 resources 插件和主代码是相同的,但执行的目标不行,目标 testCompile 和 testResources 是把 src\test\java 下的代码编译成字节码输出到 target\test-classes,同时把 src\test\resources 下的配置文件拷贝到 target\test-classes。 - package 打包插件:maven-jar-plugin
这个插件是把 class 文件、配置文件打成一个 jar(war 或其它格式)包。 - deploy 发布插件:maven-install-plugin
发布插件的功能就是把构建好的 artifact 部署到本地仓库,还有一个 deploy 插件是将构建好的 artifact 部署到远程仓库。
IDEA 中使用 Maven
基础设置
1、idea 中内置了 maven,一般不使用内置的,因为用内置修改 maven 的设置不方便。使用自己安装的 maven,需要覆盖 idea 中的默认的设置。让 idea 指定 maven 安装位置等信息。
Maven Home directory:maven 的安装目录;
User Settings File:就是 maven 安装目录 conf/setting.xml 配置文件;
Local Repository:本机仓库的目录位置;
VM Options:-DarchetypeCatalog=internal;
JRE:你项目的 jdk。
File---->Settings:设置 maven 安装主目录、maven 的 settings.xml 文件和本地仓库所在位置(为当前项目配置)。
还要在File---->New Project Settings---->Settings For New Project里面也配置(为以后新建的项目配置)。
- 配置参数:
-Dmaven.wagon.http.ssl.insecure=true -Dmaven.wagon.http.ssl.allowall=true
或
-DarchetypeCatalog=internal
-Dmaven.wagon.http.ssl.insecure=true -Dmaven.wagon.http.ssl.allowall=true -Dmaven.wagon.http.ssl.ignore.validity.dates=true -DarchetypeCatalog=internal
关于为什么要加命令参数-DarchetypeCatalog
1、是由于 IDEA 根据 maven archetype 的本质,其实是执行 mvn archetype:generate 命令,该命令执行时,需要指定一个 archetype-catalog.xml 文件,该命令的参数-DarchetypeCatalog,可选值为:remote,internal ,local等,用来指定archetype-catalog.xml文件从哪里获取。默认为remote,即从http://repo1.maven.org/maven2/archetype-catalog.xml
路径下载archetype-catalog.xml文件。
2、http://repo1.maven.org/maven2/archetype-catalog.xml
文件约为3-4M,下载速度很慢,导致创建过程卡住。所以改成了internal使用内置的xml配置文件,这样以下子就能进到项目。
建一个 maven 项目
使用模版创建项目
1、maven-archetype-quickstart:普通的java项目。
2、maven-archetype-webapp:web工程。
在窗口基本上不用修改什么,但是这样会比较慢,有时候如果网速不好,就会卡的比较久,这是因为 maven 这个骨架会从远程仓库加载 archetype 元数据,但是 archetype 又比较多,所以比较卡,这时候可以加 个属性 archetypeCatelog = internal,表示仅使用内部元数据:(配置了阿里云的话可加可不加,因为阿里云速度快)
完成后的结构:
需要手动添加 resources 文件目录:
maven 结构:
单元测试(测试方法)
1、用的是junit, junit是一个专门测试的框架(工具)。
2、junit测试的内容: 测试的是类中的方法, 每一个方法都是独立测试的。方法是测试的基本单位(单元)。
3、maven 借助单元测试,批量的测试类中的大量方法是否符合预期的。
- 使用步骤
1、加入依赖,在 pom.xml 加入单元测试依赖:
<!-- 单元测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
2、在 maven 项目中的 src/test/java 目录下,创建测试程序。
推荐的创建类和方法的提示:测试类的名称是:Test + 你要测试的类名;测试的方法名称是:Test + 方法名称。
例如你要测试HelloMaven,创建测试类 TestHelloMaven。
- 代码示例:
package com.yu;
public class App {
public int add(int i, int j){
return i + j;
}
public static void main( String[] args ) {
App app = new App();
int addNum = app.add(1,2);
System.out.println("1 + 2 = " + addNum);
}
}
package com.yu;
import org.junit.Assert;
import org.junit.Test;
public class AppTest {
@Test
public void testAdd() {
App app = new App();
int addNum = app.add(1,2);
/*
判断结果是否正确
Assert.assertEquals(期望值, 实际值)
*/
Assert.assertEquals(3, addNum);
}
}
点击进行测试:
或者点击 maven 中的 test:
测试结果:
- 其中 testAdd 叫做测试方法,定义规则如下
1、方法必须是 public。
2、方法必须没有返回值(void)。
3、方法名称是自定义的,推荐是Test + 方法名称。
4、在方法的上面加入 @Test。
maven 创建 web 项目
新建 module,选择 maven-archetype-webapp(web 工程)
建好后的结构为:
缺少一些文件,需要手动加上:
pom.xml:
<groupId>com.yu</groupId>
<artifactId>mavenWeb</artifactId>
<version>1.0</version>
<!-- web 项目打包是 war 文件-->
<packaging>war</packaging>
快捷键 Alt + Ins 可以快速搜索添加依赖。
刚添加时会报红:
点击刷新依赖:
maven 打包 web 项目
使用 package 命令打包:
打包完成后 war 包在 target 目录下:
war 文件树形结构:
- 配合服务器使用
将打包后的文件解压加到 Tomcat 所在文件夹的 webapps 目录下
bin 目录下启动 startup.bat:
启动后在浏览器访问:
依赖范围(scope)
概述
1、scope 的值有:compile(所有阶段)、test(测试阶段)、provided(已提供)。默认是 compile。
(provided:已提供,只在编译、测试时使用,意思打包时不需要带上它们,部署的环境负责提供这些 jar 文件)
2、scope:表示依赖使用的范围,也就是在 maven 构建项目的那些阶段中起作用。
3、maven 构建项目:编译、测试、打包、安装、部署过程(阶段)。
compile | test | provided | |
---|---|---|---|
对主程序是否有效 | 是 | 否 | 是 |
对测试程序是否有效 | 是 | 是 | 是 |
是否参与打包 | 是 | 否 | 否 |
是否参与部署 | 是 | 否 | 否 |
- junit 的依赖范围是 test
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
- servlet 的依赖范围是 provided
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
- 注意
1、在写项目的中的用到的所有依赖(jar 包),必须在本地仓库中有。没有必须通过 maven 下载,包括 provided 的都必须下载。
2、在 servlet 需要继承 HttpServlet(provided),你使用的 HttpServlet 是 maven 仓库中的。当写好的程序,放到 tomat 服务器中运行时,此时程序中不包含 servlet 的 jar,因为 tomcat 提供了 servlet 的 jar。
maven 常用操作
maven的全局变量
自定义的属性
1、在<properties>
通过自定义标签声明变量(标签名就是变量名)。
2、在 pom.xml 文件中的其它位置,使用${标签名}
使用变量的值。自定义全局变量一般是定义依赖的版本号,当项目中要使用多个相同的版本号时,先使用全局变量定义,再使用${变量名}
。
例:
需要修改版本的时候全部都要修改,这样很麻烦
在<properties>
里面自定义声明:
在依赖里加上:
这样修改的时候就只需要改全局变量就行了。
资源插件
1、默认没有使用resources的时候, maven执行编译代码时, 会把src/main/resource目录中的文件拷贝到target/classes目录中。
2、对于 src/main/java 目录下的非 java 不处理,不拷贝到 target/classes 目录中。
3、所以需要手动配置:
<build>
<resources>
<resource>
<directory>src/main/java</directory><!--所在的目录-->
<includes><!--包括目录下的.properties,.xml 文件都会扫描到-->
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<!-- filtering 选项 false 不启用过滤器, *.property 已经起到过滤的作用了 -->
<filtering>false</filtering>
</resource>
</resources>
</build>