Maven
Basic Maven
Published: 2021-06-06

Maven相关知识(可以结合maven.pdf来看)

maven的作用

  • maven可以管理jar文件
  • 自动下载jar和他的文档,源代码
  • 管理jar直接的依赖, a.jar需要b.jar , maven会自动下载b.jar
  • 管理你需要的jar版本
  • 帮你编译程序,把java编译为class
  • 帮你测试你的代码是否正确
  • 帮你打包文件,形成jar文件,或者war文件
  • 帮你部署项目

maven核心概念

  • POM

    pom.xml,pom翻译过来叫做项目对象模型。 maven把一个项目当做一个模型使用。控制maven构建项目的过程,管理jar依赖。

  • 约定的目录结构

    maven项目的目录和文件的位置都是规定的:

    每一个maven项目在磁盘中都是一个文件夹(项目-Hello)
      Hello/
        ---/src
        ------/main              #放你主程序java代码和配置文件
        ----------/java          #你的程序包和包中的java文件
        ----------/resources     #你的java程序中要使用的配置文件
      
        ------/test              #放测试程序代码和文件的(可以没有)
        ----------/java          #测试程序包和包中的java文件
        ----------/resources     #测试java程序中要使用的配置文件
      
        ---/pom.xml              #maven的核心文件(maven项目必须有)
      
    
  • 坐标

    一个用来表示资源的唯一的字符串

  • 依赖管理

    管理你的项目可以使用jar文件

  • 仓库管理(了解)

    你的资源存放的位置

  • 生命周期 (了解)

    maven工具构建项目的过程,就是生命周期。

  • 插件和目标(了解)

    执行maven构建的时候用的工具是插件

  • 继承

  • 聚合

疑问

  • 第一次maven compile的时候下载的是什么?

    maven工具执行的操作需要很多插件(java类--jar文件)完成的
    所以下载的是jar文件--叫做插件--插件来完成某些功能
    
  • 下载的东西存放到哪里了?

    默认仓库(本机仓库):
     C:\Users\(登录操作系统的用户名)Administrator\.m2\repository
    
  • 如何修改本机存放资源的目录位置(设置本机仓库)?

    1、修改maven的配置文件, maven安装目录/conf/settings.xml
    2、修改 <localRepository> 指定你的目录(不要使用中文目录)
    
  • maven测试的时候测的是什么代码?

    mvn test-compile 会编译项目下的测试程序(junit)
    mvn test 会运行项目下的测试程序(junit),所以测的是我们自己编写的测试代码(通常是借助junit来编写的)
    

    注意:mvn test可以单独运行,不是非得运行完mvn test-compile之后才能运行的

    具体测试步骤:

    • 在pom.xml加入单元测试依赖

      <!-- 单元测试 -->
      <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>4.11</version>
          <scope>test</scope>
      </dependency>
      
    • 在maven项目中的src/test/java目录下,创建测试程序

      推荐的创建类和方法: 1、测试类的名称 是Test + 你要测试的类名 2、测试的方法名称 是:test + 方法名称

      例子:

      // 例如你要测试HelloMaven类中的add方法
      @ExtendWith(SpringExtension.class)
      public class TestHelloMaven{
          @Test
          void testAdd(){
          }
      }
      
  • src/main/recources中的文件在编译之后被复制到哪里去了?

    该目录中的文件会被拷贝到target/classes目录中

  • main/java目录下的Java文件在编译之后被复制到哪里去了?

    执行mvn compile之后,将编译main/java/目录下的java文件为class文件, 同时把这些class文件拷贝到 target/classes目录下面

依赖管理

具体的看pdf,这里说明一下使用provided的原因:

有时候servlet的jar我们就会使用provided这个依赖范围
原因是虽然程序放到tomcat中运行的时候不包含servlet的jar,但是它依旧能够正常工作,那是因为tomcat已经提供了servlet的jar
对于这种情况的jar,我们就可以用provided这个依赖范围

plugin中的<executions>

用于配置execution目标,一个插件可以有多个目标

例如:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-checkstyle-plugin</artifactId>
    <version>3.1.1</version>
    <dependencies>
        <dependency>
            <groupId>com.puppycrawl.tools</groupId>
            <artifactId>checkstyle</artifactId>
            <version>8.39</version>
        </dependency>
    </dependencies>
    <configuration>
        <configLocation>./.checkstyle.xml</configLocation>
        <includeTestSourceDirectory>true</includeTestSourceDirectory>
        <skip>${skipTests}</skip>
    </configuration>
    <executions>
        <execution>
            <id>checkstyle</id>
            <phase>validate</phase>
            <goals>
                <goal>check</goal>
            </goals>
        </execution>
    </executions>
</plugin>

说明:

id:规定execution 的唯一标志 goals:表示目标 phase:表示阶段,目标将会在什么阶段执行 inherited:和上面的元素一样,设置false maven将会拒绝执行继承给子插件 configuration:表示此执行的配置属性

plugin中的<excludes>

用于排除

例子1:

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
        <excludes>
            <exclude>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
            </exclude>
        </excludes>
        <!-- <skip>true</skip> -->
    </configuration>
</plugin>

例子2:

<resources>
    <!-- Filter jdbc.properties & mail.properties. NOTE: We don't filter applicationContext-infrastructure.xml, 
            let it go with spring's resource process mechanism. -->
    <resource>
        <directory>src/main/resources</directory>
        <filtering>true</filtering>
        <includes>
            <include>jdbc.properties</include>
            <include>mail.properties</include>
        </includes>
    </resource>
    <!-- Include other files as resources files. -->
    <resource>
        <directory>src/main/resources</directory>
        <filtering>false</filtering>
        <excludes>
            <exclude>jdbc.properties</exclude>
            <exclude>mail.properties</exclude>
        </excludes>
    </resource>
</resources>

plugin中的<source><target>

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>2.0.2</version>
    <configuration>
        <!-- 编译代码使用的jdk版本 -->
        <source>1.8</source>
        <!-- 运行程序使用的jdk版本 -->
        <target>1.8</target>
    	<encoding>${project.build.sourceEncoding}</encoding>
    </configuration>
</plugin>

<distributionManagement>

​ 在使用maven过程中,我们在开发阶段经常性的会有很多公共库处于不稳定状态,随时需要修改并发布,可能一天就要发布一次,遇到bug时,甚至一天要发布N次。我们知道,maven的依赖管理是基于版本管理的,对于发布状态的artifact,如果版本号相同,即使我们内部的镜像服务器上的组件比本地新,maven也不会主动下载的。如果我们在开发阶段都是基于正式发布版本来做依赖管理,那么遇到这个问题,就需要升级组件的版本号,可这样就明显不符合要求和实际情况了。但是,如果是基于快照版本,那么问题就自热而然的解决了

​ maven中的仓库分为两种,snapshot快照仓库和release发布仓库。snapshot快照仓库用于保存开发过程中的不稳定版本,release正式仓库则是用来保存稳定的发行版本。定义一个组件/模块为快照版本,只需要在pom文件中在该模块的版本号后加上-SNAPSHOT即可(注意这里必须是大写),如下:

<groupId>cc.mzone</groupId>  
<artifactId>m1</artifactId>  
<version>0.1-SNAPSHOT</version>  
<packaging>jar</packaging>  

​ maven会根据模块的版本号(pom文件中的version)中是否带有-SNAPSHOT来判断是快照版本还是正式版本。如果是快照版本,那么在mvn deploy时会自动发布到快照版本库中,而使用快照版本的模块,在不更改版本号的情况下,直接编译打包时,maven会自动从镜像服务器上下载最新的快照版本。如果是正式发布版本,那么在mvn deploy时会自动发布到正式版本库中,而使用正式版本的模块,在不更改版本号的情况下,编译打包时如果本地已经存在该版本的模块则不会主动去镜像服务器上下载。

​ 所以,我们在开发阶段,可以将公用库的版本设置为快照版本,而被依赖组件则引用快照版本进行开发,在公用库的快照版本更新后,我们也不需要修改pom文件提示版本号来下载新的版本,直接mvn执行相关编译、打包命令即可重新下载最新的快照库了,从而也方便了我们进行开发。

那么如何在项目中应用snapshot和release库呢?

<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/maven-v4_0_0.xsd">  
    <modelVersion>4.0.0</modelVersion>  
    <groupId>net.aty.mybatis</groupId>  
    <artifactId>mybatis-demo</artifactId>  
    <packaging>jar</packaging>  
    <version>${project.release.version}</version>  
    <name>mybatis-demo</name>  
    <url>http://maven.apache.org</url>  
      
    <properties>  
        <project.release.version>0.1-SNAPSHOT</project.release.version>  
    </properties>  
      
  
    <profiles>  
        <profile>  
            <id>release</id>  
            <properties>  
                <project.release.version>0.1</project.release.version>  
            </properties>  
        </profile>  
    </profiles>  
      
      
    <!--定义snapshots库和releases库的nexus地址-->  
    <distributionManagement>  
        <repository>  
            <id>nexus-releases</id>  
            <url>  
                http://172.17.103.59:8081/nexus/content/repositories/releases/  
            </url>  
        </repository>  
        <snapshotRepository>  
            <id>nexus-snapshots</id>  
            <url>  
                http://172.17.103.59:8081/nexus/content/repositories/snapshots/  
            </url>  
        </snapshotRepository>  
    </distributionManagement>  
    
</project>  

首先我们看到pom文件中version的定义是采用占位符的形式,这样的好处是可以根据不同的profile来替换版本信息,比如maven默认是使用0.1-SNAPSHOT作为该模块的版本。

1、如果在发布时使用mvn deploy -P release 的命令,那么会自动使用0.1作为发布版本,那么根据maven处理snapshot和release的规则,由于版本号后不带-SNAPSHOT故当成是正式发布版本,会被发布到release仓库;

2、如果发布时使用mvn deploy命令,那么就会使用默认的版本号0.1-SNAPSHOT,此时maven会认为是快照版本,会自动发布到快照版本库。

在distributionManagement段中配置的是snapshot快照库和release发布库的地址,这里是采用nexus作为镜像服务器。对于版本库主要是id和url的配置,配置完成后就可以通过mvn deploy进行发布了,当然了,如果镜像服务器需要用户名和密码,那么还需要在maven的settings.xml文件中做如下配置:

<server>  
  <id>nexus-releases</id>  
  <username>admin</username>  
  <password>admin123</password>  
</server>  
  
<server>  
  <id>nexus-snapshots</id>  
  <username>admin</username>  
  <password>admin123</password>  
</server> 

​ 注意这里配置的server的id必须和pom文件中的distributionManagement对应仓库的id保持一致,maven在处理发布时会根据id查找用户名称和密码进行登录和文件的上传发布。

​ 我们这里通过profile的定义就可以在发布灵活切换snapshot快照版本和release正式版本了,在被依赖的组件中也可以使用profile来定义在开发阶段使用快照库,在发布阶段使用正式库的功能,只需要在不同的profile中覆盖默认的properties属性值即可。

image-20210604170119666

image-20210604170130775

<profiles>与指令中的-P

<profiles>用于声明多个环境

<profile>可以指定不同环境的不同变量值

指令中的-P用于切换环境

例子:

<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/maven-v4_0_0.xsd">  
    <modelVersion>4.0.0</modelVersion>  
    <groupId>net.aty.mybatis</groupId>  
    <artifactId>mybatis-demo</artifactId>  
    <packaging>jar</packaging>  
    <version>${project.release.version}</version>  
    <name>mybatis-demo</name>  
    <url>http://maven.apache.org</url>  
      
    <properties>  
        <project.release.version>0.1-SNAPSHOT</project.release.version>  
    </properties>  
      
    <profiles>  
        <!-- 定义id为“release”的profile -->
        <profile>  
            <id>release</id>  
            <properties>  
                <project.release.version>0.1</project.release.version>  
            </properties>  
        </profile>  
    </profiles>  
    
</project>  

现在我们可以使用-P来切换环境:

$ mvn deploy  // 如果直接这么写,那project.release.version的值就是0.1-SNAPSHOT
$ mvn deploy -P release  // 如果这么写,那project.release.version的值就是0.1

maven继承

一个 maven 项目可以继承另一个 maven 的依赖, 称为子项目、父项目

使用场景:

​ 多个子项目都需要某些依赖, 就可以把子项目共同的依赖抽取到父项目中, 子项目通过继承得到这些依赖, 这样也更好的来管理(比如升级, 删除等)

步骤:

  • 父项目的打包方式修改为 pom

    <groupId>com.ictpaas</groupId>
    <artifactId>parent</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>
    
  • 父项目使用 dependencyManagement 标签来管理, 表示子项目默认不继承, 可以配置继承, optional 表示子 pom 无论如何都不能继承

    <dependencyManagement>
        <dependencies>
            <!-- 子 pom 可以继承 -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>1.2.47</version>
            </dependency>
            <!-- 子 pom 不可以继承 -->
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>1.2.17</version>
                <optional>true</optional>
            </dependency>
        </dependencies>
    </dependencyManagement>
    
  • 子项目配置父项目

    <parent>
        <!-- 父项目坐标 -->
        <artifactId>parent</artifactId>
        <groupId>com.ictpaas</groupId>
        <version>1.0-SNAPSHOT</version>
        <!-- 父项目 pom 文件路径-->
        <relativePath>../parent/pom.xml</relativePath>
    </parent>
    
  • 子项目依赖配置

    <dependencies>
        <!-- 不需要版本, 会从父项目继承, 如果指定版本就是代表不是来自父 pom 而是子 pom 自己的. 父项目的 log4j 是不能继承的 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
        </dependency>
    </dependencies>
    

子项目不仅仅继承依赖, url, name, modeVersion等也能继承, 换句话说子 pom 文件内容很少, 看起来很简洁, 下面贴出完整的父子 pom 文件:

父 pom:

<?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.ictpaas</groupId>
    <artifactId>parent</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>

    <name>parent Maven Webapp</name>
    <!-- FIXME change it to the project's website -->
    <url>http://www.example.com</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.7</maven.compiler.source>
        <maven.compiler.target>1.7</maven.compiler.target>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.11</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>1.2.47</version>
            </dependency>
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>1.2.17</version>
                <optional>true</optional>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <finalName>parent</finalName>
        <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
            <plugins>
                <plugin>
                    <artifactId>maven-clean-plugin</artifactId>
                    <version>3.0.0</version>
                </plugin>
                <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
                <plugin>
                    <artifactId>maven-resources-plugin</artifactId>
                    <version>3.0.2</version>
                </plugin>
                <plugin>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.7.0</version>
                </plugin>
                <plugin>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <version>2.20.1</version>
                </plugin>
                <plugin>
                    <artifactId>maven-war-plugin</artifactId>
                    <version>3.2.0</version>
                </plugin>
                <plugin>
                    <artifactId>maven-install-plugin</artifactId>
                    <version>2.5.2</version>
                </plugin>
                <plugin>
                    <artifactId>maven-deploy-plugin</artifactId>
                    <version>2.8.2</version>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
</project>

子pom:

<?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>parent</artifactId>
        <groupId>com.ictpaas</groupId>
        <version>1.0-SNAPSHOT</version>
        <!-- 父项目 pom 文件路径-->
        <relativePath>../parent/pom.xml</relativePath>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>child01</artifactId>

    <dependencies>
        <!-- 不需要版本, 会从父项目继承 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
        </dependency>
    </dependencies>

</project>

<relativePath>的作用

参考:https://blog.csdn.net/zzhongcy/article/details/122085513(maven pom relativePath属性的作用)

maven聚合

image-20210606110315860

简介

在使用Java开发项目时,一种常见的情形是项目由多个模块组成,软件折及人员往往会采用各种方式对软件划分模块,以得到更清晰de设计以及更高的重用性。Maven的聚合特性能够帮助把项目的各个模块聚合在一起构建。

聚合是什么

比如有以下一个多模块项目:

image-20210606110438937

当两个模块实现之后,比如说accout-persist和account-email实现之后,一个简单的需求会自然而然的出现:如何一次构建两个项目,而不是到两个模块的目录下分别执行mvn命令。Maven聚合(多模块)的特性就是为这种需求服务的。

如何用在Maven POM表示聚合

聚合项目的POM:

<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/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.juvenxu.mvnbook.account</groupId>
	<artifactId>account-aggregator</artifactId>
	<version>1.0.0-SNAPSHOT</version>
	<packaging>pom</packaging>
	<name>Account Aggregator</name>
	<modules>
		<module>account-email</module>
		<module>account-persist</module>
		<module>account-parent</module>
	</modules>
</project>

上述聚合项目的POM聚合了三个模块,account-email, account-persist,account-parent三个模块。 POM中的name字段是为了给项目一个更容易阅读的名字,该名字会出现在Reactor反应堆构建顺序中。 是聚合实现聚合的核心配置。

聚合的表示语法

<packaging>pom</packaging>
<name>Account Aggregator</name>
<modules>
    <module>account-email</module>
    <module>account-persist</module>
    <module>account-parent</module>
</modules>

聚合的两种形式

父子目录:

image-20210606110737771

此时POM的表示形式如下:

<packaging>pom</packaging>
<name>Account Aggregator</name>
<modules>
    <module>account-email</module>
    <module>account-persist</module>
</modules>

平行目录:

image-20210606110821153

此时POM中表示聚合的形式如下:

<packaging>pom</packaging>
<name>Account Aggregator</name>
<modules>
    <module>../account-email</module>
    <module>../account-persist</module>
</modules>

相对路径理解

关键要理解module的值,这里每个module的值都是一个相对于当前POM的相对目录。

image-20210606110927866

${project.groupId}${project.version}

maven中的${project.groupId}${project.version} 表示当前项目的groupId和version。

maven依赖中的Scope、传递与隔断

可结合课件maven.pdf查阅

Scope的分类

  • compile 默认的scope,表示 dependency 都可以在生命周期中使用。而且,这些dependencies 会传递到依赖的项目中。适用于所有阶段,会随着项目一起发布。即依赖的项目会参与到当前项目的编译、运行、测试以及打包发布,是一个比较强的依赖范围。

  • test 表示dependency作用在测试时,不作用在运行时。 只在测试时使用,用于编译和运行测试代码。不会随项目发布。

  • runntime 表示dependency不作用在编译时,但会作用在运行和测试时,如JDBC驱动,适用运行和测试阶段。即是跳过编译阶段,只参与测试或运行。

  • provided 跟compile相似,但是表明了dependency 由JDK或者容器提供,例如Servlet AP和一些Java EE APIs。这个scope 只能作用在编译和测试时,同时没有传递性。 即该依赖是由系统组件提供的,我们不需要手动添加,它只存在于编译、运行和测试阶段,打包的时候并不会打进去,被剔除了的。

  • system 跟provided 相似,但是在系统中要以外部JAR包的形式提供,maven不会在repository查找它。需通过外部引入,不会在仓库中查找。例如一些特殊的jar我们或通过拷贝jar到web-info/lib下,这些jar就可以配置为system范围。

  • import

    可用于实现多继承

    参考:https://blog.csdn.net/K_520_W/article/details/84900722(maven中使用scope = import

image-20210608220355275

这里表述只是基于maven环境,有些同学在IDE(eclipse)下实践,由于IDE提供一些辅助功能,与上述记述不是十分符合。

依赖传递 如有三个项目A、B、C,当前项目为A,A依赖于B,B依赖于C。则项目C在A中是什么样的依赖关系呢? 我们可以根据B依赖于C的scope来判断:

  • scope为test、provided、system时,则项目C被抛弃,A并不依赖于C
  • 否则A依赖于C

依赖隔断 由上所述,maven的依赖关系是有传递性的。如:A–>B,B–>C,则A–>C。但有时候,项目A可能不是必需依赖C,因此需要在项目A中隔断对C的依赖。隔断依赖有2种方式:

  • 可选依赖(Optional Dependencies)

    配置optional选项,待选值为true/false。默认为false,此时依赖关系为强依赖。

    <project>
      ...
      <dependencies>
        <!-- declare the dependency to be set as optional -->
        <dependency>
          <groupId>sample.ProjectC</groupId>
          <artifactId>Project-C</artifactId>
          <version>1.0</version>
          <scope>compile</scope>
          <optional>true</optional> <!-- value will be true or false only -->
        </dependency>
      </dependencies>
    </project>
    

    这段配置为项目B依赖于项目C的配置,由于配置了optional为true,则项目A就被隔断了与项目C的依赖关系。如果想依赖C,则需要在项目A中另行配置。

  • 依赖排除(Dependency Exclusions)

    依赖排除用标签exclusions,样例如下:

    <project>  
      ...  
      <dependencies>  
        <dependency>  
          <groupId>sample.ProjectB</groupId>  
          <artifactId>Project-B</artifactId>  
          <version>1.0</version>  
          <scope>compile</scope>  
          <exclusions>  
            <exclusion>  
              <!-- declare the exclusion here -->  
              <groupId>sample.ProjectC</groupId>  
              <artifactId>Project-C</artifactId>  
            </exclusion>  
          </exclusions>   
        </dependency>  
      </dependencies>  
    </project>
    

    此配置为项目A中的配置。当项目B依赖项目C时,并没有配置optional选项时,又不能更改项目B,则可以用此种方式隔断依赖关系。

依赖关系的隔断与scope中的provided都能阻止依赖关系的传递,个人认为他们之间的区别为:

  • scope中的provided:虽然工程上隔断了关系,但此时表明,被隔断的工程是需要其它地方提供支持的,在最终运行环境中应该是一定被用到的。一般情况上层工程里一定有调用此处接口的代码。
  • 依赖关系的隔断则不一定如此,很有可能根本就不想用这个被排除的工程。

maven跳过单元测试maven.test.skipskipTests的区别

-DskipTests,不执行测试用例,但编译测试用例类生成相应的class文件至target/test-classes下。

-Dmaven.test.skip=true,不执行测试用例,也不编译测试用例类。

一、使用maven.test.skip,不但跳过单元测试的运行,也跳过测试代码的编译。

mvn package -Dmaven.test.skip=true 

也可以在pom.xml文件中修改

<plugin>  
    <groupId>org.apache.maven.plugin</groupId>  
    <artifactId>maven-compiler-plugin</artifactId>  
    <version>2.1</version>  
    <configuration>  
        <skip>true</skip>  
    </configuration>  
</plugin>  
<plugin>  
    <groupId>org.apache.maven.plugins</groupId>  
    <artifactId>maven-surefire-plugin</artifactId>  
    <version>2.5</version>  
    <configuration>  
        <skip>true</skip>  
    </configuration>  
</plugin>

二、使用mvn package -DskipTests跳过单元测试,但是会继续编译;如果没时间修改单元测试的bug,或者单元测试编译错误。使用上面的,不要用这个

<plugin>  
    <groupId>org.apache.maven.plugins</groupId>  
    <artifactId>maven-surefire-plugin</artifactId>  
    <version>2.5</version>  
    <configuration>  
        <skipTests>true</skipTests>  
    </configuration>  
</plugin>

默认idea的跳过测试采用的是第二种,所以仍然会编译代码,如果想不执行测试用例,也不编译测试用例类,那么必须采用第一种方式在pom中加上skip为true,这样才能跳过编译

image-20210720184531959

Linux环境下Maven私有库和本地库的安装与配置(Nexus)

参考:https://blog.csdn.net/weixin_40663800/article/details/83043920(Linux环境下Maven私有库和本地库的安装与配置)

需要注意的是,在配置nexus服务地址的时候,一般情况下我们会将他配置在maven的setting.xml中,但也可以写到项目的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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    
    ...
    
    <dependencies>
    	<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-quartz</artifactId>
        </dependency>
    </dependencies>
    
    <distributionManagement>
        <repository>
            <id>maven-releases</id>
            <name>Nexus Maven Release Repository</name>
            <url>http://10.30.21.22:83/repository/maven-releases/</url>
        </repository>
        <snapshotRepository>
            <id>maven-snapshots</id>
            <name>Nexus Maven Snapshot Repository</name>
            <url>http://10.30.21.22:83/repository/maven-snapshots/</url>
        </snapshotRepository>
    </distributionManagement>

    <repositories>
        <repository>
            <id>nexus</id>
            <name>Nexus Maven Repository</name>
            <url>http://10.30.21.22:83/repository/maven-public/</url>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
    </repositories>
    
    ...
    
</project>