目录
(一)Maven的生命周期
Maven构建项目的生命周期包含了项目清理,初始化,编译,测试,打包,集成测试,验证,部署和站点生成等几乎所有构建步骤。
比如我们项目中最常用的一套流程,如下图所示:Maven的生命周期是抽象的,这意味着生命周期本身不做任何实际工作,在Maven的设计中,实际任务(如代码编译)都交给插件来完成。
1.Maven的三套生命周期
在IDEA中可查看Maven的生命周期
maven的生命周期不止一套,有3套,每套里面都包含的事件如下:(1)clean:清理工作
(2)default:核心工作,例如编译,测试,打包,部署等
(3)site:产生报告,发布站点等
2.Maven常用命令
mvn clean:调用clean生命周期的clean阶段,清理上一次构建项目生成的文件;
mvn compile :编译src/main/java中的java代码;
mvn test :编译并运行了test中内容 ;
mvn package:将项目打包成可发布的文件,如jar或者war包;
mvn install :发布项目到本地仓库 ;
这些命令都可在控制台中执行,也可以在IDEA中执行,具体如下:在IDEA中,左下角有一个终端,点击,可输入指令
(二)pom.xml详解
pom(Project Object Model)指的是项目对象模型,用来描述当前的maven项目。
在之前配置Maven时,我们需要在conf目录下的setting.xml文件去配置Maven的运行环境,这个setting.xml是全局级别的配置文件,而pom.xml文件主要描述项目的maven坐标,依赖关系,开发者需要遵循的规则,组织等与项目相关的因素,是项目级别的配置文件(不同的项目需要不同的pom)。
刚创建好的项目,默认的pom.xml文件,长这个样子,如下面代码所示:
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.frank.mavenDemoOne</groupId> <artifactId>mavenDemoOne</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> </project>
一级标签(build、dependcees、depencymanagement、propertes、parent、modules)
一般我们配置了依赖之后pom.xml长的样子如下面代码所示:
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.frank.mavenDemoOne</groupId> <artifactId>mavenDemoOne</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <!--统一管理依赖版本--> <properties> <mysql.connector.version>5.1.18</mysql.connector.version> </properties> <dependencies> <!--Junit测试框架--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>RELEASE</version> </dependency> <!--mysql驱动--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>${mysql.connector.version}</version> <scope>runtime</scope> </dependency> </dependencies> <!--设置插件--> <build> <plugins> <!--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> <!--测试插件--> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.12.4</version> <configuration> <forkMode>once</forkMode> <argLine>-Dfile.encoding=UTF-8</argLine> </configuration> </plugin> <!-- tomcat7插件 --> <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.2</version> <configuration> <!--解决get请求乱码--> <uriEncoding>utf-8</uriEncoding> <port>80</port> <path>/</path> </configuration> </plugin> </plugins> </build> </project>
(三)Maven的高级特性(模块化、聚合、依赖管理)
1.Maven的依赖范围
- 我首先要理解maven的依赖范围是个啥玩意?(对概念有个基础的了解)
当使用Maven创建项目时,引入第三方jar包,对于jar包我们要对他设置它的作用范围,可以通过Maven的设置,来管理这些范围,就是让jar包在哪个环节(项目的生命周期中:编译、测试、打包)生效
- 它有哪些范围呢?这些范围的区别点在哪里呢?
编译时 src/mian路径都生效
测试时 src/test路径都生效
打包时 在打包前的时候生效
当我不设置依赖的范围说明时,它默认是什么范围呢?
- 代码怎么写?写在哪里?
通过标签<scope>来声明依赖的作用范围,写在依赖坐标里面
依赖的jar默认情况可以在任何地方可用,我们通过<scope>标签设定作用范围,作用范围主要指以下三种:(1)主程序范围有效(src/main目录范围内)
(2)测试程序范围内有效(src/test目录范围内)
(3)是否参与打包(package指令范围内)
<scope>标签的取值有五种,这五种取值与范围对应如下图所示:
示例:
2.版本维护
如果pom文件中引入的依赖太多,各种依赖又有不同的版本,为了统一维护版本,我们可以将依赖的版本号抽取出来进行统一管理。具体操作的步骤如下:
第一步:在pom.xml中使用<propeties>属性定义jar包的版本。如:
XML<properties> <junit.version>4.13</junit.version> <mybatis.version>3.4.5</mybatis.version> </properties>
第二步 :在依赖的<version>中使用${}引入前面定义好的版本
XML<dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>${junit.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>${mybatis.version}</version> <scope>compile</scope> </dependency> </dependencies>
3.依赖传递
依赖传递:
当我们在我们的项目中引入一个jar包时
引入的jar包所依赖的jar也会跟着传递进来
在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等。
4.依赖冲突
在一个项目中同时依赖了多个相同作用的jar,比如
spring-aop : 5.0.2
spring-aop : 5.0.5
我们使用maven引入了Servlet的jar包
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
当我们把项目部署到tomcat服务器上时,会报jar包冲突
因为在tomcat服务器中已经内置了servlet的jar,所以我们就得给javax.servlet的作用范围设置为provided,这样就能解决这个冲突。
5.如何解决依赖冲突
第一种方法:使用Maven通过的依赖调节原则(自动)
第一声明者优先原则
在pom文件中,先声明哪个jar包就以那个jar包为主
路径近者优先原则
优先使用我们自己导入的jar包,依赖中传递的jar包其次,直接依赖高于间接依赖
第二种方法:排除依赖的jar包
示例:
将排除依赖的jar包放入exclusion标签中
XML<dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.2.4.RELEASE</version> <!-- 排除依赖的jar包 --> <exclusions> <exclusion> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> </exclusion> </exclusions> </dependency>
第三种方法:锁定版本
示例:
将锁定的jar包放入dependencyManagement标签中,在导入jar包时就不需要写版本号
XML<!-- 锁定的jar包版本 --> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>5.0.2.RELEASE</version> </dependency> </dependencies> </dependencyManagement> <!-- 导入jar包时,不需要再设置版本 --> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> </dependency> </dependencies>
6.maven项目模块化
pojo:实体类
dao:数据处理层
service:业务逻辑层
web:响应请求
有助于进行分布式(将一个完整的系统,按照业务功能,拆分成一个个独立的子系统 ),Maven可以帮我们模块化构建项目,Maven的模块与模块之间是可以进行依赖的
7.maven项目的继承
在Java语言中,类之间是可以继承的,通过继承,子类就可以引用父类中非private的属性和方法。同样,在maven工程之间也可以继承,子工程继承父工程后,就可以使用在父工程中引入的依赖。继承的目的是为了消除重复代码。
示例:在pom.xml文件中使用<parent>标签进行父工程的继承,此图片说明父工程为MavenWeb
8.maven项目的聚合
在maven工程的pom.xml文件中可以使用<modules>标签将其他maven工程聚合到一起,聚合的目的是为了进行统一操作。
例如拆分后的maven工程有多个,如果要进行打包,就需要针对每个工程分别执行打包命令,操作起来非常繁琐。这时就可以使用<modules>标签将这些工程统一聚合到maven工程中,需要打包的时候,只需要在此工程中执行一次打包命令,其下被聚合的工程就都会被打包了。
四个工程被聚合到一个工程