- 第四部分 Maven深入
第四部分 Maven深入
-
目标
- 掌握POM文件的编写规则
- 了解Maven生命周期的概念;掌握生命周期各命令的含义
1 pom配置详解【重点】
pom(Project Object Model)指的是项目对象模型,用来描述当前的maven项目。使用pom.xml文件来实现。
【补充】
setting.xml主要用于配置maven的运行环境等一系列通用的属性,是全局级别的配置文件;而pom.xml主要描述了项目的Maven坐标,依赖关系,开发者需要遵循的规则,缺陷管理系统,组织和licenses,以及其他所有的项目相关因素,是项目级别的配置文件。
- pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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.hguo.maven</groupId>
<artifactId>maven-web2</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
</project>
【pom文件详解】
<project>
pom文件的根节点
<modelVersion>
声明项目描述符遵循哪一个POM模型版本。模型本身的版本很少改变,虽然如此,但它仍然是必不可少的,目前POM模型版本是4.0.0
<groupId>
项目组织标识符,一般是公司域名倒过来写
<artifactId>
项目标识符,即项目名
<version>
项目的版本号
<packaging>
maven项目的打包方式一般配置jar或者war
2 依赖导入【重点】
Maven的一个核心的作用就是管理项目的依赖,引入我们所需的各种jar包等。为了能自动化的解析任何一个Java构件,Maven必须将这些Jar包或者其他资源进行唯一标识,这是管理项目的依赖的基础,也就是我们要说的坐标。包括我们自己开发的项目,也是要通过坐标进行唯一标识的,这样才能才其它项目中进行依赖引用。
使用IDEA工具导入
直接在pom.xml中,新建Dependency
标签,填入artifactId
,Idea会自动联想
注意,能够自动联想的前提:
- 本地仓库已经存在的依赖(将资料中的repository.zip解压,存放至磁盘,并指定本地仓库)
- 依赖索引能够正常更新(参考《第六部分,附三》)
从远程仓库中获取坐标
如果我们导入的依赖本地仓库中没有,使用IDEA搜索就搜索不到了,我们需要从网络中查找这个依赖的坐标,然后将其添加到pom文件中。添加完成之后,maven会帮我们从私服或*仓库中下载该依赖。
搜索依赖坐标的方法:
- 在*仓库中查找:http://mvnrepository.com/
将以下坐标复制到pom文件中即可:
pom文件中引入依赖后,会去私服或者*仓库中下载依赖:如果项目结构的External Librarites中出现刚引入的依赖,则说明依赖引入成功。
3 Maven插件【了解】
-
pom.xml
<project ...> <build> <plugins> <!-- 直接在project标签里面编写一个build标签,里面再编写plugins标签,然后再插件粘贴到plugins标签里面 --> <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.2</version> <configuration> <port>8080</port> <path>/</path> </configuration> </plugin> </plugins> </build> </project>
打开Maven视图
依次打开 View
-> Tool Windows
-> Maven Projects
打开IDEA编辑区右侧Maven Projects
,会弹出如下窗口,打开窗口中的Lifecycle即可看到相关命令。
Maven官方插件
Maven官方有两个插件列表
第一个列表的GroupId为org.apache.maven.plugins,这里的插件最为成熟,具体地址为:http://maven.apache.org/plugins/index.html。
第二个列表的GroupId为org.codehaus.mojo,这里的插件没有那么核心,但也有不少十分有用,其地址为:http://mojo.codehaus.org/plugins.html。
Tomcat插件
- 配置Tomcat7插件
<!-- Tomcat7插件 -->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<port>8080</port>
<path>/</path>
</configuration>
</plugin>
- 在Maven菜单窗口,以Tomcat插件方式,运行项目
4 Maven生命周期【重点】
项目从开发的开始到项目的开发结束的整个过程
mvn clean
清理项目,清除target目录
mvn test
执行test目录下测试类和方法,所有的测试类和方法都会执行
注意:
测试类必须以"Test"结尾
mvn compile
编译main目录下所有的类,不会编译test目录下的类
mvn package
用来给项目打包,如果是java项目打包成jar包,如果是web项目打包成war包。打包好的文件在target目录。
mvn install【安装到本地仓库当中】
将打包好的jar或war包复制到本地仓库中
mvn site【了解】
生成项目站点文档
mvn deploy【了解】【安装到远程仓库当中】
将最终的包复制到远程仓库,供其他开发人员或maven项目使用
5 Maven依赖范围【重点】
三种不同的类路径
Maven在执行过程中有三种不同的classpath,它们运行Java代码的时候,使用不同的classpath类路径下的jar包来执行。三种classpath范围如下:
-
编译类路径:在main目录下可用,主程序中可用。
@Override
写代码的时候,会找父类或者找父接口,如果父类或者父接口当中有相应的方法的话,那么编译没有问题
如果在父类当中,找不到的话,就会报编译时异常
-
测试类路径:在test目录下可用,测试类中可用
现在进行一次打包的动作,maven会默认先编译,后测试,最后打包
在测试结束之后,如果测试成功的话,也意思代码当中没有一个错误,可以正常打包
那么在打包时,我们的测试代码就不需要参与打包
测试的代码,在打包之前运行,打完包之后就不需要了
也就是说在war或者是jar包里面是没有测试代码只在单元测试的时候,才会起效果,在正常运行的时候(生产环境),如果测试成功的话,那么打过的war不会有问题,所以不需要存在单元测试代码
-
运行类路径:在部署到服务上运行的时候可用,运行时可用。
Class Driver = Class.forName("com.mysql.Driver");
只要程序运行起来,就是运行类路径
常用依赖范围
依赖范围就是Java代码选择上面三个类路径中的1个或几个。在pom.xml
中通过scope
标签来配置。默认compile
,可选配置有provided
, runtime
, test
, system
, import
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId></groupId>
<artifactId></artifactId>
<version></version>
<scope>provided</scope>
</dependency>
</dependencies>
-
常见的依赖范围
mysql mysql 8.0 Class driver = Class.forName("com.mysql.Driver");
依赖范围 | 说明 | 编译classpath | 测试classpath | 运行时classpath |
---|---|---|---|---|
compile | 默认的范围,编译、测试、运行都有效 | Y | Y | Y |
provided 【重点】 |
编译、测试时有效,运行的时候不会被加入 | Y | Y | - |
runtime | 在测试、运行时有效 | - | Y | Y |
test | 只在测试时有效 | - | Y | - |
|
system
系统依赖范围。该依赖与三种classpath的关系和provided依赖范围完全一致。但是,使用system范围的依赖时必须通过systemPath元素显式地指定依赖文件的路径。由于此依赖不是通过Maven仓库解析的,而且往往与本机系统绑定,可能造成构建的不可移植,因此应该谨慎使用。systemPath元素可以引用环境变量。
例如:oracle的驱动包,从*仓库无法下载,需要先下载到本地,再通过本地路径引入。先下载orace的包到本地:
然后在pom文件中导入依赖:
<dependency>
<groupId>oracle</groupId>
<artifactId>ojdbc</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>D:/software/maven/apache-maven-3.5.2/repository/ojdbc6.jar</systemPath>
</dependency>
依赖范围配置
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.9.RELEASE</version>
<!--compile是默认的依赖范围,可以不用写出来-->
<scope>compile</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.0.8</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>oracle</groupId>
<artifactId>ojdbc</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>D:/software/maven/apache-maven-3.5.2/repository/ojdbc6.jar</systemPath>
</dependency>
6 依赖版本统一维护【了解】
如果pom文件中引入的依赖太多,各种依赖又有不同的版本,为了统一维护版本。我们可以将依赖的版本号抽取出来进行统一管理。抽取方法如下:
第一步 :在pom.xml中使用<propeties>
属性定义jar包的版本
<properties>
<spring.version>4.2.4.RELEASE</spring.version>
<struts.version>2.3.8</struts.version>
</properties>
第二步 :在依赖的
<properties>
<spring.version>4.2.4.RELEASE</spring.version>
<struts.version>2.3.8</struts.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-spring-plugin</artifactId>
<version>${struts.version}</version>
</dependency>
</dependencies>
-
Maven坐标
- 组织id
- 项目id
- 版本号
-
Maven仓库
- 本地
- 远程
- 私服
- *
- 第三方
-
依赖导入
-
-
-
-
生命周期
-
clean
清除编译后的文件
-
test
运行测试
注意:
必须以Test结尾
-
compile
先测试,再编译,生成.class文件
-
install
先测试,再编译,生成class文件,打包,将jar或war安装到本地仓库
-
package
先测试,编译,生成 class文件,打包
-
-
Maven依赖范围
编译、测试、运行
-
compile
-
test
-
provided
测试、编译
-
附一 完整的pom.xml配置
<?xml version="1.0" encoding="UTF-8"?>
<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.hguo.maven.usermanager-maven</groupId>
<artifactId>usermanager-maven</artifactId>
<version>2.0-SNAPSHOT</version>
<packaging>war</packaging>
<!--统一管理依赖版本-->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<c3p0.version>0.9.1.2</c3p0.version>
<beanutils.version>1.8.3</beanutils.version>
<commons.logging.version>1.1.1</commons.logging.version>
<fastjson.version>1.2.47</fastjson.version>
<servlet.version>3.0.1</servlet.version>
<jstl.version>1.2</jstl.version>
<mysql.connector.version>5.1.18</mysql.connector.version>
<spring.version>4.2.4.RELEASE</spring.version>
</properties>
<dependencies>
<!--c3p0-->
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>${c3p0.version}</version>
</dependency>
<!--commons-beanutils-->
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>${beanutils.version}</version>
</dependency>
<!--commons-logging-->
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>${commons.logging.version}</version>
</dependency>
<!--fastjson-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<!--jackson-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.2.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.2.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.2.3</version>
</dependency>
<!--servlet3-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>${servlet.version}</version>
<scope>provided</scope>
</dependency>
<!--jstl-->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>${jstl.version}</version>
</dependency>
<!--mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.connector.version}</version>
<scope>runtime</scope>
</dependency>
<!--spring-jdbctemplate-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
</dependencies>
</project>
附二 清理maven仓库
初始情况下,我们的本地仓库是没有任何jar包的,此时会从远程仓库去下载(如果没有配置,就直接从*仓库去下载),可能由于网络的原因,jar包下载不完全,这些不完整的jar包都是以lastUpdated结尾。此时,maven不会再重新帮你下载,需要你删除这些以lastUpdated结尾的文件。如果本地仓库中有很多这样的以lastUpadted结尾的文件,可以执行如下脚本来删除
在上面的bat文件上右键---》编辑 。修改文件:
修改完毕后,双击运行即可删除maven仓库中的残留文件。
附三 更新依赖索引
有时候给idea配置完maven仓库信息后,在idea中依然搜索不到仓库中的jar包。这是因为仓库中的jar包索引尚未更新到idea中。这个时候我们就需要更新idea中maven的索引了,具体做法如下:
打开设置----搜索maven----Repositories----选中本地仓库-----点击Update
<dependencies>
<dependency>
<groupId>组织id</groupId>
<artifactId>项目id</artifactId>
<version>版本号</version>
<scope>依赖范围(重点项:provided)</scope>
</dependency>
</dependencies>