maven入门
一、Maven
1、简介
Maven是一种比较流行的服务于Java平台的自动化构建工具,对于生产环境下多框架、多模块整合开发有着重要的作用。
2、未使用Maven前存在的问题:
(1)一个项目即为一个工程。
问题:未使用Maven前,一个项目即为一个工程。如果项目非常大时,使用package来划分模块,会显得非常臃肿。
解决:最好是将一个模块作为一个工程,然后由多个工程组成一个完整的项目,便于分工合作。使用Maven可以将一个项目拆分成多个工程。
(2)项目中使用的jar包,需要手动导入。
问题:同样的jar文件会重复出现在不同的项目工程中。一方面会浪费存储空间,另一方面会使工程显得臃肿。
解决:最好将jar包放到某个文件夹(仓库)中,当某工程需要使用时,直接“引用“仓库里的文件,并不需要将其复制一份并导入。使用Maven可以将jar包放入仓库并进行管理。
(3)项目所需的jar包,需要自己手动下载。
问题:不同官网提供jar包下载的方式是不同的。使用不同方式下载的jar包可能不一定是规范的。
解决:最好大多数jar包按照统一的规范存在某一个仓库中,然后可以直接下载规范的jar包。使用Maven可以解决。
(4)一个jar包依赖的其他jar包,需要手动加入到项目中。
问题:所有jar包的依赖关系都需要清楚的了解,增加了学习的难度。
解决:使用Maven可以自动的将某jar包所依赖的jar包导入。
3、构建
(1)什么是构建(不是创建)?
以“Java源文件”、“框架配置文件”、“JSP”、“HTML”、“图片”等资源为原材料,去“生产”一个可以运行的项目的过程叫做构建。分为编译、部署。
(2)编译:
Java源文件(.java) --》编译 --》字节码文件(.class) --》JVM执行。
(3)部署:
一个BS项目运行的并不是动态的Web工程本身,而是编译后的Web工程。写好的Web工程经过编译后,部署到相应的位置,启动服务器,才会去调用。
对于文件路径的写法,以编译后的目录结构为准。、
4、构建的流程
(1)清理:将之前编译的字节码(.class)文件删除,为下一次编译做准备。
(2)编译:将Java源程序(.java)编译成字节码文件(.class)。
(3)测试:自动测试,自动调用Junit程序。
(4)报告:报告程序执行的结果。
(5)打包:动态的Web工程打war包,Java工程打jar包。
(6)安装:将打包的文件复制到maven仓库的指定位置。
(7)部署:将war包复制到servlet容器指定的目录下,使其可以运行。
注:使用maven,可以自动化构建,省去了编译、打包、部署等操作。
二、Maven安装
1、下载
去官网下载, 网址为: http://maven.apache.org/download.cgi
2、检查JDK是否存在
由于Maven是由Java编写的,其需要JDK才能运行。若没有,则需要安装JDK。
命令行输入:
java -version 可以打印JDK版本
3、解压、配置环境变量
比如我解压在 F:\maven 下 修改系统环境变量(类似于JDK配置环境变量): 添加MAVEN_HOME或M2_HOME,指向包路径, 即F:\maven\apache-maven-3.3.9 PATH环境变量最后面加上 ;%MAVEN_HOME%\bin 输入mvn -version 或者 mvn -v,如果出现maven版本信息,则表示配置成功。
三、Maven核心概念
1、概念:
(1)约定的目录结构。
(2)POM。
(3)坐标。
(4)依赖(重点)。
(5)仓库。
(6)生命周期、插件、目标。
(7)继承。
(8)聚合。
2、约定的目录结构:
ProjectName |----------src |----------|----------main |----------|----------|----------java |----------|----------|----------resources |----------|----------test |----------|----------|----------java |----------|----------|----------resources |----------target |----------|----------classes |----------pom.xml 其中: ProjectName目录:表示的是 工程名。 src目录:表示的是 源码。 target目录:表示的是 编译、打包后的文件。 pom.xml目录:表示的是 maven核心配置文件。 main目录:表示的是 存放主程序. test目录:表示的是 存放测试程序. class目录:表示的是 编译的字节码文件. java目录:表示的是 存放java源文件. resources目录:表示的是 存放框架或者其他工具的配置文件。 为什么要遵循约定的目录结构? Maven负责自动化构建项目,以编译为例,maven想要自动进行编译,则必须知道java源文件的位置在哪, 按照约定的目录结构去找java源程序 为maven提供了便利。 注: 约定 > 配置 > 编码, 即能使用配置解决的,就不用编码去实现。 能使用约定解决的,就不用配置去实现。
3、常用的mvn命令
执行 与构建过程相关的maven命令时(编译、测试、打包等),必须进入pom.xml所在的目录,再开始执行命令。 注:若不在pom.xml目录下执行以下命令,会报错的。 常用命令: mvn clean; 清理 mvn compile; 编译主程序 mvn test-compile; 编译测试程序 mvn test; 执行测试 mvn package; 打包 mvn install; 安装maven工程到本地仓库 mvn site; 生成站点
4、maven联网问题
(1)maven的核心程序仅定义了抽象的生命周期,具体的工作必须由不同的插件完成,但是这些插件并没有包含在maven的核心程序中。
(2)当执行某maven命令 需要使用某些插件时,首先会从本地仓库(一般为当前系统用户下的 .m2 文件夹里的 repository 文件夹里,即 C:\Users\当前用户名\.m2\repository, 比如:C:\Users\Administrator\.m2\repository)中查找。如果本地仓库中找不到想要的插件,则会自动联网去maven的中央仓库下载。若此时无法连接外网,则会执行失败。
5、手动使用maven下载jar包
(1)maven 中央仓库 地址为 :https://mvnrepository.com/
(2)进入地址后,搜索想要找的jar包。比如:mybatis。
(3)点击,进入MyBatis,并点击某个版本,比如3.5.1.
(4)点击进入3.5.1后,复制代码。
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.1</version> </dependency>
(5)在电脑上某位置创建一个文件夹,然后,在文件夹中新建一个文件(pom.xml),并将复制的代码粘贴到pom.xml的 <dependencies>标签下。如下:
<?xml version="1.0" encoding="UTF-8"?> <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <modelVersion>4.0.0</modelVersion> <groupId>test.download</groupId> <artifactId>test.download</artifactId> <version>1.0.0</version> <dependencies> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.1</version> </dependency> </dependencies> </project>
(6)执行下载操作。
方法一:
通过命令行,进入pom.xml所在的目录,并执行以下代码,执行成功后,会得到一个target文件夹,里面就是相关的jar包。
call mvn -f pom.xml dependency:copy-dependencies
方法二:
使用bat脚本下载jar包的操作。在文件夹中新建一个文件(.bat文件),比如test.bat,并向文件内写入以下内容。然后执行 test.bat 文件即可。同样得到一个target文件夹。
::使用DOS命令执行mvn命令:将pom.xml文件所依赖的jar包从maven中央仓库拷贝到本地
call mvn -f pom.xml dependency:copy-dependencies
@pause
(7)通过以上步骤下载的jar包,会自动拷贝一份在 C:\Users\Administrator\.m2\repository 文件夹下。
6、修改本地仓库的默认读取位置
(1)找到maven解压包的下的 conf\settings.xml 文件。
比如: F:\maven\apache-maven-3.3.9\conf\settings.xml
(2)在 settings.xml 文件中 找到 <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> --> 【修改为:】 <!-- 比如我的本地仓库路径为:F:\maven\repository, 则修改为:--> <!-- 注意,原文件是被注释的,需要从中取出 --> <localRepository>F:\maven\repository</localRepository>
(3)配置镜像
<mirrors> <mirror> <id>nexus-aliyun</id> <mirrorOf>*</mirrorOf> <name>Nexus aliyun</name> <url>http://maven.aliyun.com/nexus/content/groups/public</url> </mirror> </mirrors>
7、POM
(1)POM : Project Object Model 项目对象模型。
(2)pom.xml是maven工程的核心配置文件,与构建过程相关的所有设置均在这个文件中配置。
8、坐标
(1)数学中:
平面上,可以通过X, Y两个向量,唯一定位平面中的一点。
空间上,可以通过X,Y,Z三个向量,唯一定位空间中的一点。
(2)maven中:
使用三个向量唯一定位一个maven工程。
<!-- groupId,一般为 公司域名反写 + 项目名 --> <groupId>test.download</groupId> <!-- artifactId,一般为模块名 --> <artifactId>test.download</artifactId> <!-- version, 一般为版本号 --> <version>1.0.0</version>
(3)maven的向量与目录的对应关系:
<groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> 会对应到 本地仓库中 : junit\junit\4.12\junit-4.12.jar 即 groupId\artifactId\version\artifactId-version.jar 其中 groupId中若为test.download型, 则会转为 test\download
9、仓库
(1)本地仓库:存在于当前电脑中,为当前电脑的所有maven工程服务。
(2)远程仓库:
私服:搭建在局域网中,为局域网范围内的所有maven工程服务。
中央仓库:搭建在Internet上,为全世界范围内的maven工程服务。
中央仓库镜像:为了分担中央仓库的压力,给访问分流,提升访问效率。
(3)仓库保存的东西是什么?
保存maven自身所需要的插件。
保存第三方(第一方指JDK,第二方指开发人员)框架或工具的jar包。
保存自己开发的maven工程。
即仓库保存的就是各种jar包。
10、依赖
(1)maven解析依赖信息(即解析<dependency>标签的内容)时,会首先从本地仓库进行查找被依赖的jar包。
对于自己开发的maven工程,进入相应的pom.xml所在的目录,执行 mvn install命令后,可以将自己开发的maven工程放到本地仓库中 。
(2)依赖的范围(<scope>标签的内容):
compile(默认)依赖范围:
对主程序有效。
对测试程序有效。
对打包有效(即参与打包)。
对部署有效。
test依赖范围:
对主程序无效。
对测试程序有效。
对打包无效。
对部署无效
比如:Junit
provided依赖范围:
对主程序无效。
对测试程序有效。
对打包无效。
对部署无效。
比如:servlet-api.jar
<dependencies> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.1</version> <scope>compile</scope> </dependency> </dependencies>
(3)写依赖时,不能乱写,比如如果将jsp-api.jar包的scope设为compile的话,可能造成空指针异常,因为可能会与其他框架的jar包冲突了。
(4)依赖的传递性:当一个模块工程A在pom.xml中配置了相关依赖信息,则其他模块工程B使用这个模块工程A时,不需要再额外的配置依赖的信息了,其会从A中传递到B中。
注:只有compile范围的依赖才能进行传递。test、provided范围的依赖需要在每个工程中手动配置。
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.1.8.RELEASE</version> <scope>compile</scope> </dependency> </dependencies>
(5)依赖的删除(使用<exclusion>标签)
在项目工程中,删除不希望出现的jar包。
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.1.8.RELEASE</version> <scope>compile</scope> <exclusions> <exclusion> <groupId>org.springframework</groupId> <artifactId>spring-jcl</artifactId> </exclusion> </exclusions> </dependency> </dependencies>
(6)传递依赖的原则:
作用:解决多个模块工程间的jar包冲突问题。
原则:(jar包冲突时)
路径最短者优先原则,即传递依赖发生时,优先选择距离该工程最近的jar包。
路径相同时,先声明者优先。即<dependency>标签先声明的jar包被使用。
注:非传递依赖时(即直接依赖),以最后的<dependency>标签声明的jar包为主。
(7)统一管理jar包的版本号
使用<properties>标签,并自定义标签来声明版本号。
在<version>标签中,使用${自定义标签名}来引用。
【未修改前:】 <properties> <jar.version>5.1.7.RELEASE</jar.version> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${jar.version}</version> <scope>compile</scope> </dependency> </dependencies>
【修改时,只需修改自定义标签即可,当有多个地方需要修改时,可以很方便的修改】 <properties> <jar.version>5.1.8.RELEASE</jar.version> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${jar.version}</version> <scope>compile</scope> </dependency> </dependencies>
11、生命周期
(1)生命周期指的是各个构建环节的执行流程。
(2)maven的核心程序中定义了抽象的生命周期,生命周期的各阶段的具体任务由不同的插件来完成。
(3)为了更好的实现自动化构建,maven的核心程序对于生命周期的每个阶段,都从最开始执行,到该生命周期阶段 结束。比如执行 mvn compile 命令时,会从最开始执行,直到compile结束。
(4)插件和插件目标:
生命周期的各阶段仅定义了要执行什么任务。
各阶段与不同的插件目标(插件目标指的是调用插件的命令)相对应。
相似的目标由特定的插件来解决。
12、继承
(1)为什么使用继承?
对于非compile范围(test,provided)的依赖,由于不能进行依赖传递,所以需要在每个模块工程中单独定义,可能造成各个模块工程间的jar版本不一致。
所以需要使用一个父工程,并定义好这些依赖信息,令每个模块继承父工程,即可获得非compile范围的依赖信息。对依赖版本修改时,只需修改父工程即可。
注意:每个子工程中相关的非compile范围的依赖仍需写,只是不需要再写版本号了。由父工程统一管理版本号。
注意:使用继承后,在执行maven安装工程的命令时(maven install),需要先将父工程安装,再安装子工程。若直接安装子工程,可能会报错。
(2)继承的操作步骤
第一步:创建一个父工程(Eclipse创建maven工程见下面的: 四、Eclipse中使用Maven),并添加相关的非compile范围的依赖。
注意:创建时的打包方式需要选择 pom。
【父工程的pom.xml】 <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.test.maven</groupId> <artifactId>mavenDemo</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>pom</packaging> </project>
第二步:在子工程中声明父工程。并去除子工程中提示重复依赖的信息(可选操作)。
【子工程的pom.xml】 <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.maven.lyh</groupId> <artifactId>demo2</artifactId> <!-- <version>0.0.1-SNAPSHOT</version> --> <!--在子工程中声明父工程 --> <parent> <groupId>com.test.maven</groupId> <artifactId>mavenDemo</artifactId> <version>0.0.1-SNAPSHOT</version> <!-- 以子工程的pom.xml文件的位置为基准,找到父工程pom.xml的位置 --> <relativePath>../mavenDemo/pom.xml</relativePath> </parent> </project>
第三步:在父工程中统一管理依赖信息。
<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.test.maven</groupId> <artifactId>mavenDemo</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>pom</packaging> <!-- 统一管理依赖配置信息 --> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.1.7.RELEASE</version> <scope>test</scope> </dependency> </dependencies> </dependencyManagement> </project>
第四步:在子工程中声明相应的依赖信息(注意:版本号无需写,写了的话,继承没意义了,相当于重新配置的依赖信息)
<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.maven.lyh</groupId> <artifactId>demo2</artifactId> <!--在子工程中声明父工程 --> <parent> <groupId>com.test.maven</groupId> <artifactId>mavenDemo</artifactId> <version>0.0.1-SNAPSHOT</version> <!-- 以子工程的pom.xml文件的位置为基准,找到父工程pom.xml的位置 --> <relativePath>../mavenDemo/pom.xml</relativePath> </parent> <!--在子工程中声明非compile范围的配置信息 --> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <!-- <version>5.1.7.RELEASE</version> --> <scope>test</scope> </dependency> </dependencies> </project>
此时即可看到子工程中出现了父工程所配置的依赖信息。
当父工程修改配置信息时,所有的子工程的配置信息将会一起改变。
13、聚合
(1)作用:未使用聚合前,对每个模块工程,需要一个个的安装,使用聚合后,会一键安装,只需安装父工程即可。
(2)步骤:
第一步:在父工程中配置聚合。
<!-- 配置聚合 --> <modules> <!-- 根据当前pom.xml的位置,配置子工程所在的路径,maven会自动管理install顺序 --> <module>../demo2</module> <module>../demo3</module> </modules> 【pom.xml】 <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.test.maven</groupId> <artifactId>mavenDemo</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>pom</packaging> <!-- 配置聚合 --> <modules> <!-- 根据当前pom.xml的位置,配置子工程所在的路径 --> <module>../demo2</module> <module>../demo3</module> </modules> <!-- 统一管理依赖配置信息 --> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.1.8.RELEASE</version> <scope>test</scope> </dependency> </dependencies> </dependencyManagement> </project>
第二步:在父工程中执行mvn install即可。
四、Eclipse中使用Maven
1、Maven插件
(1)Eclipse已内置一个maven插件。
(2)配置:
Installations:指定maven核心程序的位置。一般不使用Eclipse内置的maven插件的程序。使用自己下载的maven程序。
User Settings:指定 conf\setting.xml的位置,用于定位本地仓库的位置。
2、Eclipse中新建一个maven的Java工程
(1)File -- > New -- > Maven Project 。 如果没找到Maven Project,可以File -- > New -- > Other中去搜索Maven Project 。
(2)勾选Create a simple project,并选择 next。
(3)输入Group Id(公司域名反写)以及 Artifact Id(项目模块名),点击finish即可。
(4)注意:默认的JDK版本是1.5的。
(5)修改maven默认的JDK版本。
找到conf\settings.xml文件,并在<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> </properties> </profile>
3、Eclipse中执行maven命令
找到pom.xml文件,右击,并选择 Run As, 然后选择需要执行的命令即可。
4、Eclipse中新建一个Web工程
(1)File -- > New -- > Maven Project
(2)勾选Create a simple project,并选择 next。
(3)输入Group Id(公司域名反写)以及 Artifact Id(项目模块名),注意,Packaging要选择war。最后点击finish即可。
(4)注意,此时的Web项目还需进一步配置,此时webapp为空。
找到项目,右击,选择Properties, 并选择 Project Facets, 找到Dynamic Web Module,将其设为不选中,点击Apply。
再次点击Dynamic Web Module, 将其设为选中,会出现如下的画面。
点击Further configuration available,进入后 ,将Content directory设置为src\main\webapp,并勾选Generate web.xml deployment descriptor, 最后点OK即可。
此时webapp下有了相关的文件。
(5)当写一个jsp文件时,会出现错误,这个是缺少了相关的jar包。可通过pom.xml配置依赖。
在pom.xml中,添加如下代码:
<!-- 由于服务器里有servlet-api,所以可以给一个scope为provide -->
<dependencies> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> <scope>provide</scope> </dependency> </dependencies>
(6)使用mvn install安装模块工程到maven仓库时,要注意运行环境要选择JDK,而不是JRE,JRE可能会报错。