maven入门

如何手动创建一个简单maven项目?

  • 创建项目目录
mkdir my_maven_project
cd my_maven_project/
vi pom.xml
// 参考官网的basics示例
<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>
 
  <groupId>me.heoller</groupId>
  <artifactId>my_maven_project</artifactId>
  <version>1.0-SNAPSHOT</version>
</project>
  • 创建代码目录
// maven默认会编译项目目录中src/main/java目录下的java文件(约定大于配置)
mkdir -p src/main/java
vi src/main/java/Hello.java
  • 编写一个Hello类
package me.heoller;
public class Hello {
    public String say(String word) {
        return word;
    }
}
  • 项目编译
mvn compile
[INFO] Scanning for projects...
[INFO]
[INFO] --------------------< me.heoller:my_maven_project >---------------------
[INFO] Building my_maven_project 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ my_maven_project ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory /Users/henry/my_work/my_maven_project/src/main/resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ my_maven_project ---
[INFO] Changes detected - recompiling the module!
[WARNING] File encoding has not been set, using platform encoding UTF-8, i.e. build is platform dependent!
// 可以看到maven已将类文件编译成功了。
[INFO] Compiling 1 source file to /Users/henry/my_work/my_maven_project/target/classes
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  1.104 s
[INFO] Finished at: 2021-03-31T22:00:15+08:00
[INFO] ------------------------------------------------------------------------
  • 添加资源文件目录以及资源文件
// maven默认会编译项目目录中src/main/resources目录下的资源文件(约定大于配置)
mkdir -p src/main/resources && \
touch src/main/resources/hello.properties && \
echo "name=heoller" >> src/main/resources/hello.properties
  • 项目编译
mvn compile
[INFO] Scanning for projects...
[INFO]
[INFO] --------------------< me.heoller:my_maven_project >---------------------
[INFO] Building my_maven_project 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ my_maven_project ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 1 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ my_maven_project ---
[INFO] Changes detected - recompiling the module!
[WARNING] File encoding has not been set, using platform encoding UTF-8, i.e. build is platform dependent!
[INFO] Compiling 1 source file to /Users/henry/my_work/my_maven_project/target/classes
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  1.352 s
[INFO] Finished at: 2021-03-31T22:10:32+08:00
[INFO] ------------------------------------------------------------------------

打包

mvn package
[INFO] Scanning for projects...
[INFO]
...
[INFO]
// 默认会在打包的时候,执行测试用例
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ my_maven_project ---
[INFO] No tests to run.
[INFO]
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ my_maven_project ---
[INFO] Building jar: /Users/henry/my_work/my_maven_project/target/my_maven_project-1.0-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  1.557 s
[INFO] Finished at: 2021-03-31T22:12:51+08:00
[INFO] ------------------------------------------------------------------------

执行测试用例

不使用junit时,mvn默认会执行Test开头的类中test开头的测试方法

  • 创建测试代码目录
// 约定大于配置
mkdir -p src/test/java
  • 编写测试类
package me.heoller;
# mvn默认会执行Test开头的类中test开头的测试方法
public class TestHello {
    public void testHello() {
        System.out.println("unit test....");
    }
}
  • 执行测试
mvn test
...
Running me.heoller.TestHello
unit test....
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.002 sec
Results :
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  1.748 s
[INFO] Finished at: 2021-03-31T22:22:38+08:00
[INFO] ------------------------------------------------------------------------

使用junit时,只会执行加了@Test注解的测试方法

  • 引入junit包
<dependencies>
  <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <type>jar</type>
    <scope>test</scope>
    <optional>true</optional>
  </dependency>
</dependencies>
  • 修改测试类
package me.heoller;
import org.junit.Test;
public class TestHello {
    @Test
    public void testHello() {
        System.out.println("unit test....");
    }
}

依赖管理

本地仓库

<localRepository>/path/to/local/repo</localRepository>

核心配置

项目依赖

依赖传播特性

当项目依赖了spring-context后,mvn会将spring-context所依赖的包也加载进来。 mvn依赖传播

依赖优先原则

当出现不同版本的依赖时,mvn会依赖优先原则选择组件版本:

  1. 最短路径
  2. 相同路径时取先配置的组件

可选依赖

可选依赖不会被传递,optional默认值为false。

<optional>true</optional>

排除依赖

<exclusions>
  <exclusion>
    <groupId>org.springframework</groupId>
    <artifactId>spring-beans</artifactId>
  </exclusion>
</exclusions>

依赖范围

通过<scope>设置。

可选值 说明
compile 默认值,编译和打包都会依赖
provided 编译依赖,打包不依赖
runtime 编译不依赖,打包依赖
test 只有测试类才会依赖jar包中的类,打包不依赖
system 可引入系统classpath中指定的包和非maven库中的第三方包,编译时依赖,打包不依赖

处理项目运行时system范围的jar包

  • 针对classpath中的jar包,将对应的jar包路径配置到系统的classpath中即可,而不需要打到包中
<dependency>
  <groupId>com.sun</groupId>
  <artifactId>tools</artifactId>
  <scope>system</scope>
  <systemPath>${java.home}/../lib/tools.jar</systemPath>
</dependency>
  • 使用maven-dependency-plugin将项目lib目录中的第三方jar包打到包中
<dependency>
  <groupId>com.heoller</groupId>
  <artifactId>heoller</artifactId>
  <scope>system</scope>
  <systemPath>${project.basedir}/lib/heoller.jar</systemPath>
</dependency>

项目聚合与继承

聚合

配置示例

<modules>
  <module>xxx-xxx</module>
</modules>

继承(properties, dependencies, build)

配置示例

<parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-parent</artifactId>
  <version>2.4.4</version>
</parent>

依赖管理

父项目中配置了依赖管理,子项目需要显式声明dependency才会继承父项目中的依赖。

<dependencyManagement>
  <dependencies></dependencies>
</dependencyManagement>

项目属性

通过properties标签指定,引用方式${}

默认属性

属性 说明
basedir 项目根目录
version 项目版本号
project.basedir 同basedir
project.version 同version
project.build.directory 构建目录,默认target
project.build.sourceEncoding 源码编码格式
project.build.sourceDirectory 源码路径
project.build.finalName 输出包文件名
project.build.outputDirectory 构建输出目录,默认target/classes

项目构建配置

构建资源配置

resources

  • 配置示例
<build>
  <resources>
    <resource>
      <directory>src/main/resources</directory>
      <includes>
        <include>**/*</include>
        <include>*</include>
      </includes>
      <filtering>true</filtering>
    </resource>
    <resource>
      <directory>src/main/java</directory>
      <includes>
        <include>**/*.xml</include>
      </includes>
      <filtering>true</filtering>
    </resource>
  </resources>
</build>
  • 说明
resource子标签 说明
targetPath 资源文件目标路径
directory 资源文件路径, 默认位于${basedir}/src/main/resources
includes 配置参与构建的资源文件
excludes 配置忽略的资源文件
filtering 默认false,true表示将资源文件中的${key}在编译时进行替换,替换源: -Dkey指定值 或 pom中的值 或 filters中指定的properties文件

编译插件

...

profile指定编译环境

...