Maven
1.什么是Maven
Maven是项目进行模型抽象,充分运用的面向对象的思想,Maven可以通过一小段描述信息来管理项目的构建,报告和文档的软件项目管理工具。Maven 除了以程序构建能力为特色之外,还提供高级项目管理工具。由于 Maven 的缺省构建规则有较高的可重用性,所以常常用两三行 Maven 构建脚本就可以构建简单的项目。
说白了: Maven是由Apache开发的一个工具。用来管理java项目(依赖(jar)管理, 项目构建, 分模块开发 ,管理项目的生命周期).
2.Maven的作用
-
依赖管理:maven对项目的第三方构件(jar包)进行统一管理。向工程中加入jar包不要手工从其它地方拷贝,通过maven定义jar包的坐标,自动从maven仓库中去下载到工程中。
-
项目构建:maven提供一套对项目生命周期管理的标准,开发人员、和测试人员统一使用maven进行项目构建。项目生命周期管理:编译、测试、打包、部署、运行。
-
maven对工程分模块构建,提高开发效率。
3.Maven仓库和坐标※
3.1Maven的仓库
仓库名称 | 作用 |
---|---|
本地仓库 | 相当于缓存,工程第一次会从远程仓库(互联网)去下载jar 包,将jar包存在本地仓库(在程序员的电脑上)。第二次不需要从远程仓库去下载。先从本地仓库找,如果找不到才会去远程仓库找。 |
中央仓库 | 仓库中jar由专业团队(maven团队)统一维护。中央仓库的地址:https://repo1.maven.org/maven2/ |
远程仓库 | 在公司内部架设一台私服,其它公司架设一台仓库,对外公开。 |
maven坐标搜索网站的地址: https://mvnrepository.com/
3.2 Maven的坐标
Maven的一个核心的作用就是管理项目的依赖,引入我们所需的各种jar包等。为了能自动化的解析任何一个Java构件,Maven必须将这些Jar包或者其他资源进行唯一标识,这是管理项目的依赖的基础,也就是我们要说的坐标。包括我们自己开发的项目,也是要通过坐标进行唯一标识的,这样才能才其它项目中进行依赖引用。坐标的定义元素如下:
-
groupId:项目组织唯一的标识符,实际对应JAVA的包的结构 (一般写公司的组织名称 eg:com.itheima,com.alibaba)
-
artifactId: 项目的名称
-
version:定义项目的当前版本
<dependecies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.9</version>
</dependency>
</dependecies>
4.Maven的安装
4.1下载Mavn:
4.2安装Maven:
将Maven压缩包解压,即安装完毕。
4.3Maven目录:
文件名 | 内容 |
---|---|
bin | 命令 |
boot | 第三方类加载框架 |
conf | 配置 |
lib | maven自身jar包 |
4.4配置环境变量:
配置MAVEN_HOME和Path
MAVEN_HOME | 安装路径 |
---|---|
Path | %MAVEN_HOME%\bin |
4.5配置本地仓库:
-
在本地创建文件夹repository
-
在maven的安装目录中conf/ settings.xml文件,在这里配置本地仓库
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd"> <!-- 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:/source/Maven/repository</localRepository>
4.6测试Maven安装成功:
打开cmd本地控制台,输入mvn -version
5.IDEA集成Maven
-
配置Maven
-
配置参数(解决创建慢的问题) -DarchetypeCatalog=internal
-
新创建project,一定不要使用原来的project,第一次使用maven创建项目的时候,一定要联网。
6.Maven的常用命令
3.1clean命令
清除编译产生的target文件夹内容,可以配合相应命令一起使用,如mvn clean package, mvn clean test
3.2 compile命令
该命令可以对src/main/java目录的下的代码进行编译
3.3 test命令
测试命令,先将src/main/java以及src/test/java中的类都进行编译,然后再执行src/test/java/下所有junit的测试用例
3.4 package命令
mvn package,打包项目
先编译,再执行测试,然后再打包(只会将main/java里面的代码打到包)
-
如果是JavaSe的项目,打包成jar包
-
如果是JavaWeb的项目,打包成war包
3.5 install命令
mvn install,打包后将其安装在本地仓库
3.6生命周期
7.依赖管理和插件
3.1导入依赖
导入依赖坐标,无需手动导入jar包就可以引入jar。在pom.xml中使用<dependency>标签引入依赖。
做项目/工作里面 都有整套的依赖的, 不需要背诵的.
去Maven官网找, 赋值,粘贴. http://mvnrepository.com/
导入junit坐标依赖:
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
3.2 依赖范围
依赖范围 | 对于编译classpath有效 | 对于测试classpath有效 | 对于运行时classpath有效 | 例子 |
---|---|---|---|---|
compile | Y | Y | Y | spring-core |
test | - | Y | - | Junit |
provided | Y | Y | - | servlet-api |
runtime | - | Y | Y | JDBC驱动 |
system | Y | Y | - | 本地的,maven仓库之外的类库 |
-
compile 编译、测试、运行,A在编译时依赖B,并且在测试和运行时也依赖
例如:strus-core、spring-beans, C3P0,Druid。打到war包或jar包
-
provided 编译、和测试有效,A在编译和测试时需要B
例如:servlet-api就是编译和测试有用,在运行时不用(tomcat容器已提供)
不会打到war
-
runtime:测试运行有效,
例如:jdbc驱动包 ,在开发代码中针对java的jdbc接口开发,编译不用
在运行和测试时需要通过jdbc驱动包(mysql驱动)连接数据库,需要的
会打到war
-
test:只是测试有效,只在单元测试类中用
例如:junit
不会打到war
-
按照依赖强度,由强到弱来排序:(理解)
compile> provided> runtime> test
8.Maven插件
Maven是一个核心引擎,提供了基本的项目处理能力和建设过程的管理,以及一系列的插件是用来执行实际建设任务。maven插件可以完成一些特定的功能。例如,集成jdk插件可以方便的修改项目的编译环境;集成tomcat插件后,无需安装tomcat服务器就可以运行tomcat进行项目的发布与测试。在pom.xml中通过plugin标签引入maven的功能插件。
-
JDK编译版本的插件
<!--jdk编译插件--> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.2</version> <configuration> <source>1.8</source> <target>1.8</target> <encoding>utf-8</encoding> </configuration> </plugin>
-
Tomcat7服务端的插件(部署项目)
<plugins> <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <configuration> <!-- 指定端口 --> <port>82</port> <!-- 请求路径 --> <path>/</path> </configuration> </plugin> </plugins>
注意: Maven的中央仓库中只有Tomcat7.X版本的插件,而之前我们使用的是8.X的版本,如果想使Tomcat8.X的插件可以去其他第三方仓库进行寻找,或者使用IDEA集成外部Tomcat8极其以上版本,进行项目的发布。
9.修改maven的配置
一、修改不使用骨架创建maven项目的默认编译版本
-
不使用骨架创建的maven项目的默认编译版本是1.5或者1.4版本
<profile> <id>jdk1.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> <encoding>UTF-8</encoding> </properties> </profile> 将上述标签内容添加到settings文件的<profiles>标签中
二、彻底解决引入依赖的时候卡、报错
-
修改settings.xml文件,添加如下代码
<mirrors> <mirror> <id>alimaven</id> <name>aliyun maven</name> <url>http://maven.aliyun.com/nexus/content/groups/public/</url> <mirrorOf>central</mirrorOf> </mirror> <mirror> <id>uk</id> <mirrorOf>central</mirrorOf> <name>Human Readable Name for this Mirror.</name> <url>http://uk.maven.org/maven2/</url> </mirror> <mirror> <id>CN</id> <name>OSChina Central</name> <url>http://maven.oschina.net/content/groups/public/</url> <mirrorOf>central</mirrorOf> </mirror> <mirror> <id>nexus</id> <name>internal nexus repository</name> <url>http://repo.maven.apache.org/maven2</url> <mirrorOf>central</mirrorOf> </mirror> </mirrors>
三、注意点
-
引入依赖之后,要检查依赖是否引入成功
-
如果dependencies中大块报红
-
先使用cleanLastUpdated文件,进行清理。清完之后刷新
-
检查自己的maven配置是否正确
-
检查settings.xml中的本地仓库路径配置是否正确
-
将所有的依赖删除,接着一个一个依赖添加,添加一个就刷新一下,看是否添加成功,如果发现了哪个依赖报错,很有可能是因为你的本地仓库中没有该版本,所以我们可以尝试切换版本
-
10.maven 私服
10.1Maven私服概述
公司在自己的局域网内搭建自己的远程仓库服务器,称为私服, 私服服务器即是公司内部的 maven 远程仓库, 每个员工的电脑上安装 maven 软件并且连接私服服务器,员工将自己开发的项目打成 jar 并发布到私服服务器,其它项目组从私服服务器下载所依赖的构件(jar)。私服还充当一个代理服务器,当私服上没有 jar 包会从互联网中央仓库自动下载,如下图 :
10.2.搭建私服环境
10.2.1 下载 nexus
Nexus 是 Maven 仓库管理器, 通过 nexus 可以搭建 maven 仓库,同时 nexus 还提供强大的仓库管理功能,构件搜索功能等。 下载地址: http://www.sonatype.org/nexus/archived/
下载: nexus-2.12.0-01-bundle.zip
10.2.2安装 nexus
-
解压 nexus-2.12.0-01-bundle.zip,进入 bin 目录:
-
以管理员权限运行命令行,进入 bin 目录,执行 nexus.bat install
-
安装成功在服务中查看有 nexus 服务
10.2.3卸载nexus
cmd 进入 nexus 的 bin 目录,执行: nexus.bat uninstall
10.2.4启动 nexus
-
方式一
cmd 进入 bin 目录,执行 nexus.bat start
-
方式二
直接启动 nexus 服务
10.2.5登录
-
访问: http://localhost:8081/nexus/
查看 nexus 的配置文件 conf/nexus.properties ,里面有端口号
-
点击右上角的 Log in,输入账号和密码 登陆 (账号admin,密码admin123 )
-
登录成功
10.2.6仓库类型
nexus 的仓库有 4 种类型:
-
hosted,宿主仓库, 部署自己的 jar 到这个类型的仓库,包括 releases 和 snapshot 两部 分, Releases 公司内部发布版本仓库、 Snapshots 公司内部测试版本仓库
-
proxy,代理仓库, 用于代理远程的公共仓库,如 maven 中央仓库,用户连接私服,私 服自动去中央仓库下载 jar 包或者插件。
-
group,仓库组,用来合并多个 hosted/proxy 仓库,通常我们配置自己的 maven 连接仓 库组。
-
virtual(虚拟):兼容 Maven1 版本的 jar 或者插件
11.Maven私服的使用
11.1.将项目发布到私服
11.1.1需求
企业中多个团队协作开发通常会将一些公用的组件、开发模块等发布到私服供其它团队或模块开发人员使用。 本例子假设多团队分别开发 . 某个团队开发完在common_utils, 将 common_utils发布到私服供 其它团队使用.
11.1.2配置
第一步: 需要在客户端即部署common_utils工程的电脑上配置 maven环境,并修改 settings.xml文件(Maven配置文件), 配置连接私服的用户和密码 。此用户名和密码用于私服校验,因为私服需要知道上传的账号和密码是否和私服中的账号和密码一致 (配置到<servers>标签下)
<server>
<id>releases</id>
<username>admin</username>
<password>admin123</password>
</server>
<server>
<id>snapshots</id>
<username>admin</username>
<password>admin123</password>
</server>
releases: 连接发布版本项目仓库 snapshots: 连接测试版本项目仓库
第二步: 在需要发布配置项目 pom.xml . 配置私服仓库的地址,本公司的自己的 jar 包会上传到私服的宿主仓库,根据工程的版本号决定上传到哪个宿主仓库,如果版本为 release 则上传到私服的 release 仓库,如果版本为snapshot 则上传到私服的 snapshot 仓库 .
<distributionManagement>
<repository>
<id>releases</id>
<url>http://localhost:8081/nexus/content/repositories/releases/</url>
</repository>
<snapshotRepository>
<id>snapshots</id>
<url>http://localhost:8081/nexus/content/repositories/snapshots/</url>
</snapshotRepository>
</distributionManagement>
-
注意: pom.xml 这里<id> 和 settings.xml 配置 <id> 对应!
11.1.3测试
1、 首先启动 nexus 2、 对 common_utils工程执行 deploy 命令
根据本项目pom.xml中version定义决定发布到哪个仓库,如果version定义为snapshot,执行 deploy后查看 nexus 的 snapshot仓库, 如果 version定义为 release则项目将发布到 nexus的 release 仓库,本项目将发布到 snapshot 仓库:
11.2 从私服下载 jar 包
11.2.1需求
没有配置 nexus 之前,如果本地仓库没有,去中央仓库下载,通常在企业中会在局域网内部署一台私服服务器, 有了私服本地项目首先去本地仓库找 jar,如果没有找到则连接私服从私服下载 jar 包,如果私服没有 jar 包私服同时作为代理服务器从中央仓库下载 jar 包,这样做的好处是一方面由私服对公司项目的依赖 jar 包统一管理,一方面提高下载速度, 项目连接私服下载 jar 包的速度要比项目连接中央仓库的速度快的多。
本例子测试从私服下载 commons-utils工程 jar 包。
11.2.2在 settings.xml 中配置仓库
在客户端的 settings.xml 中配置私服的仓库,由于 setting.xml 中没有 repositories 的配置标签需要使用 profile 定义仓库。(配置在<profiles>
标签下)
<profile>
<!--profile 的 id-->
<id>dev</id>
<repositories>
<repository>
<!--仓库 id, repositories 可以配置多个仓库,保证 id 不重复-->
<id>nexus</id>
<!--仓库地址,即 nexus 仓库组的地址-->
<url>http://localhost:8081/nexus/content/groups/public/</url>
<!--是否下载 releases 构件-->
<releases>
<enabled>true</enabled>
</releases>
<!--是否下载 snapshots 构件-->
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<!-- 插件仓库, maven 的运行依赖插件,也需要从私服下载插件 -->
<pluginRepository>
<!-- 插件仓库的 id 不允许重复,如果重复后边配置会覆盖前边 -->
<id>public</id>
<name>Public Repositories</name>
<url>http://localhost:8081/nexus/content/groups/public/</url>
</pluginRepository>
</pluginRepositories>
</profile>
使用 profile 定义仓库需要激活才可生效。
<activeProfiles>
<activeProfile>dev</activeProfile>
</activeProfiles>
11.2.3测试从私服下载 jar 包
-
删掉本地仓库的day01_javase_02
-
编译依赖day01_javase_02的工程
12.maven的依赖传递
12.1 什么是依赖传递
在maven中,依赖是可以传递的,假设存在三个项目,分别是项目A,项目B以及项目C。假设C依赖B,B依赖A,那么我们可以根据maven项目依赖的特征不难推出项目C也依赖A。
web项目直接依赖了spring-webmvc,而spring-webmvc依赖了sping-aop、spring-beans等。最终的结果就是在我们的web项目中间接依赖了spring-aop、spring-beans等。
12.2 什么是依赖冲突
由于依赖传递现象的存在, spring-webmvc 依赖 spirng-beans-4.2.4,spring-aop 依赖 spring-beans-5.0.2,但是发现 spirng-beans-4.2.4 加入到了工程中,而我们希望 spring-beans-5.0.2 加入工程。这就造成了依赖冲突。
12.3 如何解决依赖冲突
-
第一声明者优先原则
哪个jar包在靠上的位置,这个jar包就是先声明的,先声明的jar包下的依赖包,可以优先引入项目中。
其实就是根据坐标导入的顺序来确定最终使用哪个传递过来的依赖。
-
路径近者优先原则
直接依赖比传递依赖路径近,你那么最终进入项目的jar包会是路径近的直接依赖包。
直接依赖:项目中直接导入的jar包就是项目的直接依赖包。
传递依赖(间接依赖):项目中没有直接导入的jar包,可以通过中直接依赖包传递到项目中去。
修改jar包,直接引入依赖spring-core
<!--导入相关依赖包--> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>4.2.4.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.2.RELEASE</version> </dependency> <!--引入直接依赖--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>4.2.8.RELEASE</version> </dependency> </dependencies>
-
排除依赖
可以使用exclusions标签将传递过来的依赖排除出去。
<!--导入相关依赖包--> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>4.2.4.RELEASE</version> <!--直接排除--> <exclusions> <exclusion> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.2.RELEASE</version> </dependency> </dependencies>
-
版本锁定
采用直接锁定版本的方法确定依赖jar包的版本,版本锁定后则不考虑依赖的声明顺序或依赖的路径,以锁定的版本为准添加到工程中,此方法在企业开发中经常使用。
版本锁定的使用方式:
第一步:在dependencyManagement标签中锁定依赖的版本
<!--锁定jar版本--> <dependencyManagement> <dependencies> <!-- Mybatis --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>${mybatis.version}</version> </dependency> </dependencies> </dependencyManagement>
第二步:在dependencies标签中声明需要导入的maven坐标
<dependencies> <!-- Mybatis --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>${mybatis.version}</version> </dependency> </dependencies>
13.分模块构建maven工程
工程分层后的开发:所有的service和dao的代码都在一起,1:增强程序的通用性,2:降低了代码的耦合性
13.1maven工程的继承
在maven工程之间也可以继承,子工程继承父工程后,就可以使用在父工程中引入的依赖。继承的目的是为了消除重复代码。如果将 dao、 service、 web 分开创建独立的工程则每个工程的 pom.xml 文件中的内容存在重复,比如:设置编译版本、锁定 spring 的版本的等,可以将这些重复的 配置提取出来在父工程的 pom.xml 中定义。
13.2 maven工程的聚合
在maven工程的pom.xml文件中可以使用<modules>标签将其他maven工程聚合到一起,聚合的目的是为了进行统一操作。
例如拆分后的maven工程有多个,如果要进行打包,就需要针对每个工程分别执行打包命令,操作起来非常繁琐。这时就可以使用<modules>标签将这些工程统一聚合到maven工程中,需要打包的时候,只需要在此工程中执行一次打包命令,其下被聚合的工程就都会被打包了。