使用 Maven 多年了,但是没有系统的看过相关资料,零零散散的看过些教程,自己凭感觉去使用,也踩了一些坑,现在好好理一下。
Maven 生命周期
这是 maven 的默认生命周期,每一个阶段的命令会执行之前所有阶段的命令。
需要注意的是执行 mvn package 命令,最终的打包生成的格式是在 pom.xml 中指定的 <packaging>jar</packaging>
项目构建习惯
假如我现在要构建一个工程。
父工程
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<packaging>pom</packaging>
<!--子模块-->
<modules>
<module>provider-payment9002</module>
</modules>
<groupId>cn.caiqz</groupId>
<artifactId>cloud2020</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>cloud2020</name>
<description>父工程</description>
<!-- packaging pom 总工程-->
<!--统一管理jar包版本-->
<properties>
<!--略-->
</properties>
<!--子模块继承之后,提供作用:锁定版本+子module不用写groupId和version-->
<dependencyManagement><!--定义规范,但不导入-->
<dependencies>
<!--spring boot 统一依赖管理-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.1.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--spring cloud alibaba 统一依赖管理-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.1.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--spring cloud 统一依赖管理-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
这里说下spring-boot-dependencies
、spring-cloud-alibaba-dependencies
、spring-cloud-dependencies
是个什么东东。
先看这个,以前我们自己构建项目父工程时,会把spring boot starter作为父工程放入我们的父工程中。
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.0.RELEASE</version>
</parent>
那如果我不止想引入Spring boot下的依赖,我还想引入Spring Cloud Alibaba全家桶中的组件呢?总不能再去继承一次吧!
所以可以引入相应dependencies来进行管理。
子模块
<?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">
<parent>
<artifactId>cloud2020</artifactId>
<groupId>cn.caiqz</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>provider-payment9002</artifactId>
<modelVersion>4.0.0</modelVersion>
<description>
子模块
</description>
<dependencies>
<!--引入nacos-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!--引入spring boot web支持-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Boot的健康监控-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
</project>
Maven 的一些技巧
- 加快编译速度,配置上
-DarchetypeCatalog=internal
参数。
建议按下图操作,对所有新建的工程生效,免得每次每个工程都跑来设置。
- 解决 jar 包冲突
在引入依赖的时候指定该 dependency 的作用范围<scope></scope>
- compile:默认值,适用于所有阶段(表明该 jar 包在编译、运行以及测试中路径均可见),并且会随着项目一起发布。
- test:只在测试时使用,用于编译和运行测试代码,不会随项目发布。
- runtime:无需参与项目的编译,不过后期的测试和运行周期需要其参与,与 compile 相比,跳过了编译。如 JDBC 驱动,适用运行和测试阶段。
- provided:编译和测试时有效,但是该依赖在运行时由服务器提供,并且打包时也不会被包含进去。如 servlet-api。
- system:类似 provided,需要显式提供包含依赖的 jar,不会从 maven 仓库下载,而是从本地文件系统获取,需要添加 systemPath 的属性来定义路径。
例如,引入 Sevlet 依赖的时候会跟 Maven 自带 Tomcat 插件中的 sevlet 包冲突,就会导致项目启动失败,此时将 sevlet 的依赖加上<scope>provided</scope>
即可。