一. Maven是什么
Maven是目前最流行的自动化构建工具,并不是作用域代码开发的任何一层,跟Git一样,对辅助编码没有作用,在开发环境中,一个大的项目往往需要很多的工程,一个项目不仅仅是一个工程。在这个时候,多个工程整合在一起,那么就需要使用Maven这种自动化构建工具。
二. Maven解决了什么问题
①: 我们现在的开发,一个项目就是一个工程,如果项目非常庞大,就不再适合使用package来划分模块,最好的方式就是每个模块就是一个全新的工程,对于我们工作的划分协调和代码维护来说,借助Maven就可以将一个项目拆分成多个工程。
②:每做一个项目就要往lib目录下添加n多个jar包
③:所有的项目中jar包都需要手动添加到项目中,所以存在很多相同的jar包重复的存放在很多的项目中,造成项目的体积庞大。
④:jar包之间的依赖关系,我们很难确定。
⑤:我们一个正常的功能开发:编码—编译—打包—部署—测试,这5个环节,实际上真正需要人操作的就只有编码和测试,其他的都是程式化的操作,现在的Eclipse可以帮我们进行自动编译,但是不能完成自动打包及自动部署。
以上提出的5个问题,都是maven可以解决的问题。
三. 什么是构建
构建的过程就是我们编写的Java代码,框架的配置文件,国际化等等其他的资源文件,jsp,图片等等作为原材料,去生产一个可以运行的项目的过程,这才叫做构建。
四. Maven的安装
- 检查JAVA_HOME环境变量(有没有配置jdk)
- 下载解压Maven核心程序
- 配置Maven环境变量
添加M2_HOME环境变量后,再添加到Path中。
4.查看Maven版本信息验证安装是否正确
打开cmd,输入mvn -v
至此为止,Maven安装就结束了。
下面来配置一下Maven核心程序
①:找到安装目录下的conf文件夹 下的setting.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>F:/wbyq/maven/repository</localRepository> //本地仓库
<!-- 远程仓库,使用阿里云镜像-->
<mirror>
<id>alimaven</id>
<mirrorOf>central</mirrorOf>
<name>aliyun maven</name>
<url>https://maven.aliyun.com/nexus/content/groups/public/</url>
</mirror>
</mirrors>
五. eclipse中添加本地的Maven
点击add添加,并apply
Global Settings是全局配置
现在eclipse中就添加好了Maven.
六. 新建Maven项目
解释一下目录结构:
src/main/java: 以后我们主要写java程序的目录
src/main/resources: 配置文件的存放地址
src/test/java: 测试程序的目录(一般不用)
target: maven编译后的结果存放的目录
**pom.xml(重点)😗*依赖的配置文件
七. 依赖
- 依赖的目的:当一个jar包A需要使用到jar包B中的程序,那么A就对B产生了依赖,这是在概念上的描述,实际开发过程配置需要在pom.xml 文件中使用dependencies 和 dependency 标签来指定依赖的jar包就可以了。
例:
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.0</version>
<scope>test</scope>
</dependency>
</dependencies>
- 依赖的范围:
大家注意到在依赖的配置中,除了所需要依赖jar包的坐标之外,还有一个scope设置,scope表示的是范围,这里指的就是依赖的范围,依赖的范围有几个可选值,常用的有三个:
- test : test范围依赖的jar包只服务于测试程序
- compile :compile范围依赖的jar包服务于主程序,也服务器测试程序
- provided :provided 范围依赖的jar包服务于主程序,也服务器测试程序
那么对于compile范围和provided范围的依赖区别在哪里呢?
Compile和provided 范围的区别在于,Compile是参与部署的依赖jar包,而provided 范围是不参与部署的依赖的jar包。
我们可以创建一个Maven的web工程来测试一番。
依赖的有效性总结:
Test | Compile | provided | |
---|---|---|---|
主程序 | × | √ | √ |
测试程序 | √ | √ | √ |
参与部署 | × | √ | × |
- 依赖的传递
在A工程中依赖b.jar,b.jar中依赖c.jar,如果A工程工程中对b.jar的依赖是compile范围,b.jar中依赖的c.jar也是compile范围,则b.jar会将依赖的c.jar传递给A工程。
Maven工程 | 依赖的范围 | 对A工程的可见性 | ||
---|---|---|---|---|
A | B | C | compile | √ |
D | test | × | ||
E | provided | × |
-
依赖的排除:
依赖的排除:当我们当前工程中依赖了B jar包,而B jar包又依赖了C jar包,如果依赖的方位是compile范围,这个时候C jar包就会被B jar包传递给当前工程,如果说依赖自动传递的jar包 c是一个不稳定版本的jar包,或者对当前的工程会产生影响,那么我们当前工程可以在依赖B jar包的时候将传递过来的C jar包排除
<dependency>
<groupId>com.wanbangee.maven</groupId>
<artifactId>HelloFriend</artifactId>
<version>0.0.1-SNAPSHOT</version>
<type>jar</type>
<scope>compile</scope>
<!-- 依赖的排除 -->
<exclusions>
<exclusion>
<groupId>com.wanbangee.maven</groupId>
<artifactId>Hello</artifactId>
</exclusion>
</exclusions>
</dependency>
5.依赖的原则:jar包冲突解决原则,在MakeFriends中依赖了HelloFriend,HelloFriend中依赖了Hello,并且将依赖的Hello传递给了MakeFriends,现在我们在MakeFriends中直接依赖Hello,这个时候有两个Hello,造成了冲突,那么MakeFriends中使用哪个Hello呢?
1) 路径最短者优先
2) 路径相同时,先声明者优先
- 一管理依赖的jar包版本统:比如我们在开发SSM工程的时候,我们需要依赖很多的Spring的jar包,那么这些Spring jar包如core ,beans,context,aop,excepress等等,肯定使用同一个版本的,这个时候我们最好统一声明版本,这样有利于我们jar包的升级。
<properties>
<wanbang.spring.version>5.1.5.RELEASE</wanbang.spring.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${wanbang.spring.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${wanbang.spring.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
八. 继承
为什么需要继承呢?由于非compile范围的依赖不能在依赖链中传递,所以需要每个工程单独配置非compile范围的依赖,就比如我们junit依赖。如果现在各个工程的junit版本都需要是4.9,那么这个时候各个工程手动去修改无疑是不可取的,使用继承就可以将这样的依赖信息统一到父工程中进行统一管理。
①创建父工程,一般都使用Java工程,唯一需要注意的是打包方式为pom。
②在父工程中配置jar包的依赖
<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.wanbangee.maven</groupId>
<artifactId>Parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
③在子工程中引用父工程
<?xml version="1.0" ?>
<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>
<!--
几何中的坐标:
- 平面中,使用x,y坐标可以确定平面中的唯一的一个点
- 在空间中,使用x,y,z坐标可以确定空间中的唯一的一个点
Maven中的坐标:
使用三个坐标可以确定Maven仓库中唯一的一个jar包
groupId:公司或组织域名倒序+当前项目名称
artifactId:当前项目中的模块名称
version:当期模块的版本
-->
<!-- <groupId>com.wanbangee.maven</groupId> -->
<artifactId>Hello</artifactId>
<!-- <version>0.0.1-SNAPSHOT</version> -->
<parent>
<!-- 引用父工程的坐标
如果子工程的坐标 groupId 和 version 与父工程一致,则可以省略子工程坐标groupId 和 version 声明
-->
<groupId>com.wanbangee.maven</groupId>
<artifactId>Parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<!-- 配置当前工程目录到父工程的pom.xml文件的相对路径 -->
<relativePath>../Parent/pom.xml</relativePath>
</parent>
<name>Hello</name>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
</dependencies>
</project>
九. 聚合
为什么需要聚合?将一个项目拆分成一个工程之后,需要手动逐个安装到仓库后才能够生效,修改后每个工程都需要单独的进行maven的各项操作。所有聚合之后,就可以对聚合的所有的工程统一的执行maven指令,比如打包,安装…
聚合的配置非常简单:
<!-- 聚合 -->
<modules>
<module>../Hello</module>
<module>../HelloFriend</module>
<module>../MakeFriends</module>
<module>../HelloWorld</module>
<module>OurFriend</module>
</modules>
注意点:需要在pom打包方式的工程中配置聚合。