强哥叨逼叨

V1

2022/03/18阅读:33主题:萌绿

要面试了?Maven相关知识都给你整理好了

哈喽,大家好,我是强哥。

现在正值金三银四的好时节,面试前的准备必然不能少,毕竟一次好的面试准备对于是否能找到好的OFFER和提高自己的薪资有很大的帮助。

强哥最近也开始整理一些面试资料给大家,都是良心收集,童叟无欺,干货满满。

今天送上的是Maven专题。Let's Go!!!

Maven里的modelVersion是什么?

modelVersion 描述这个POM文件是遵从哪个版本的项目描述符。项目描述符其实就是XML文件需要遵循的XSD规则。

<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>
</project>

modelVersion:指定了当前POM模型的版本,模型本身的版本很少改变,虽然如此,但它仍然是必不可少的,这是为了当Maven引入了新的特性或者其他模型变更的时候,确保稳定性。对于Maven 2及Maven 3来说,它只能是4.0.0。

父(Super)POM的概念是什么?

父(Super)POM是 Maven 默认的 POM(类似Java的Object类是其他类的公共父类)。所有的 POM 都继承自一个父 POM(无论是否显式定义了这个父 POM)。父 POM 包含了一些可以被继承的默认设置。因此,当 Maven 发现需要下载 POM 中的 依赖时,它会到 Super POM 中配置的默认仓库 http://repo1.maven.org/maven2 去下载。

使用以下命令来查看 Super POM 默认配置:

mvn help:effective-pom
scm配置的作用

软件配置管理的(SCM:Software Configuration Management)它可以支持我们常用SVN、CVS、GIT等。

我们知道,代码版本管理工具都有自己独特的命令来操作提交变更、或从服务器上获取最新的源码,如SVN及CVS的操作就很不相同,使用Maven担任的SCM机制,就可以使得SCM的操作变得统一

scm配置:

 <!--SCM(Source Control Management)标签允许你配置你的代码库,供Maven web站点和其它插件使用。 -->
    <scm>
        <!--SCM的URL,该URL描述了版本库和如何连接到版本库。欲知详情,请看SCMs提供的URL格式和列表。该连接只读。 -->
        <connection>
            scm:svn:http://svn.baidu.com/banseon/maven/banseon/banseon-maven2-trunk(dao-trunk)
        </connection>
        <!--给开发者使用的,类似connection元素。即该连接不仅仅只读 -->
        <developerConnection>
            scm:svn:http://svn.baidu.com/banseon/maven/banseon/dao-trunk
        </developerConnection>
        <!--当前代码的标签,在开发阶段默认为HEAD -->
        <tag />
        <!--指向项目的可浏览SCM库(例如ViewVC或者Fisheye)的URL。 -->
        <url>http://svn.baidu.com/banseon</url>
    </scm>

对应maven plugin配置:

<plugins>
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-scm-plugin</artifactId>
    <version>1.8.1</version>
    <configuration>
      <connectionType>developerConnection</connectionType>
    </configuration>
  </plugin> 
</plugins>

常用命令:

  • 提交
mvn -Dmessage="<commit_log_here>" scm:checkin
  • 更新
mvn scm:update
dependencyManagement的作用

继承自该项目的所有子项目的默认依赖信息。这部分的依赖信息不会被立即解析,而是当子项目声明一个依赖(必须描述group ID和 artifact ID信息),如果group ID和artifact ID以外的一些信息没有描述,则通过group ID和artifact ID 匹配到这里的依赖,并使用这里的依赖信息。

使用dependencyManagement可以统一管理项目的版本号,确保应用的各个项目的依赖和版本一致,不用每个模块项目都弄一个版本号,不利于管理,当需要变更版本号的时候只需要在父类容器里更新,不需要任何一个子项目的修改;如果某个子项目需要另外一个特殊的版本号时,只需要在自己的模块dependencies中声明一个版本号即可。子类就会使用子类声明的版本号,不继承于父类版本号。

在父模块中:

<dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.44</version>
            </dependency>
        </dependencies>
</dependencyManagement>

那么在子模块中只需要groupIdartifactId即可,如:

 <dependencies>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
 </dependencies>
dependencyManagement与dependencies区别
  • Dependencies相对于dependencyManagement,所有生命在dependencies里的依赖都会自动引入,并默认被所有的子项目继承。

  • dependencyManagement里只是声明依赖,并不自动实现引入,因此子项目需要显示的声明需要用的依赖。如果不在子项目中声明依赖,是不会从父项目中继承下来的;只有在子项目中写了该依赖项,并且没有指定具体版本,才会从父项目中继承该项,并且version和scope都读取自父pom;另外如果子项目中指定了版本号,那么会使用子项目中指定的jar版本。

Maven构建配置文件的类型和激活方式有哪些?

构建配置文件大体上有三种类型:

类型 在哪定义
项目级(Per Project) 定义在项目的POM文件pom.xml中
用户级 (Per User) 定义在Maven的设置xml文件中 (%USER_HOME%/.m2/settings.xml)
全局(Global) 定义在 Maven 全局的设置 xml 文件中 (%M2_HOME%/conf/settings.xml)

有配置文件如下:

<profiles>
      <profile>
          <id>test</id>
          ……
      </profile>
      <profile>
          <id>prod</id>
          ……
      </profile>
</profiles>

配置文件激活方式:

  • 使用命令控制台输入显式激活。
mvn test -Ptest

第一个 test 为 Maven 生命周期阶段,第 2 个 test 为构建配置文件指定的 id 参数,这个参数通过 -P 来传输,当然,它可以是 prod 或者 normal 这些由你定义的id

  • 通过 maven 设置。
<settings 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/settings-1.0.0.xsd"
>

   ...
   <activeProfiles>
      <activeProfile>test</activeProfile>
   </activeProfiles>
</settings>
  • 基于环境变量(用户或者系统变量)。 这个需要在 pom.xml 里面的 id 为 test 的 profile 节点,加入 activation 节点:
<profiles>
      <profile>
          <id>test</id>
          <activation>
            <property>
               <name>env</name>
               <value>test</value>
            </property>
          </activation>
          ……
      </profile>
</profiles>

然后执行命令:

mvn test -Denv=test
  • 操作系统设置(比如说,Windows系列)。 activation 元素包含下面的操作系统信息。当系统为 windows XP 时,test Profile 将会被触发。
<profile>
   <id>test</id>
   <activation>
      <os>
         <name>Windows XP</name>
         <family>Windows</family>
         <arch>x86</arch>
         <version>5.1.2600</version>
      </os>
   </activation>
</profile>

然后执行命令:

mvn test
  • 文件的存在或者缺失。 现在使用 activation 元素包含下面的操作系统信息。当 target/generated-sources/axistools/wsdl2java/com/companyname/group 缺失时,test Profile 将会被触发。
<profile>
   <id>test</id>
   <activation>
      <file>
         <missing>target/generated-sources/axistools/wsdl2java/
         com/companyname/group</missing>
      </file>
   </activation>
</profile>

然后执行命令:

mvn test
聊聊你对Maven插件的理解

Maven 有以下三个标准的生命周期:

  • clean:项目清理的处理
  • default(或 build):项目部署的处理
  • site:项目站点文档创建的处理 每个生命周期中都包含着一系列的阶段(phase)。这些 phase 就相当于 Maven 提供的统一的接口,然后这些 phase 的实现由 Maven 的插件来完成。

我们在输入 mvn 命令的时候 比如 mvn clean,clean 对应的就是 Clean 生命周期中的 clean 阶段。但是 clean 的具体操作是由 maven-clean-plugin 来实现的。

所以说 Maven 生命周期的每一个阶段的具体实现都是由 Maven 插件实现的。

插件通常提供了一个目标的集合,并且可以使用下面的语法执行:

mvn [plugin-name]:[goal-name]

例如,一个 Java 工程可以使用 maven-compiler-plugin 的 compile-goal 编译,使用以下命令:

mvn compiler:compile
如何自定义Maven插件

我们经常在写pom的时候,会在build的几点里面配有各式各样的plugin,这些plugin就是maven的插件,他们通常叫做Mojo,这些插件的作用就是在构建项目的过程中,执行一些动作,行为,例如使用maven-jar-plugin的插件,就是用于打包jar。又例如,我们在使用spring boot的时候,为什么执行mvn spring-boot:run的时候,maven会做一些spring-boot的构建方式,是因为我们在build里面配有了spring-boot-maven-plugin的插件,并且执行了run的类。

自定义插件步骤:

1、创建一个maven项目,引入两个插件,一个是maven-plugin-api,一个是maven-plugin-annotations,用上这两个插件,我们才能编写属于我们的自定义插件

<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.test.maven</groupId>
  <artifactId>my-maven-plugin</artifactId>
  <packaging>maven-plugin</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>my-maven-plugin Maven Mojo</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <dependency>
      <groupId>org.apache.maven</groupId>
      <artifactId>maven-plugin-api</artifactId>
      <version>2.0</version>
    </dependency>
    <dependency>
      <groupId>org.apache.maven.plugin-tools</groupId>
      <artifactId>maven-plugin-annotations</artifactId>
      <version>3.1</version>
    </dependency>
  </dependencies>
</project>

2、写插件实现java执行类,需要继承AbstractMojo类,和重写execute方法,里面就是具体我们要实行的的逻辑,添加关键注解

// mojo注解就是maven插件的注解。name就是后面使用该插件的时候excuation里面的,
// 后面配置的是生命周期,即默认是安装时候执行本插件(这个可以在pom文件指定)
@Mojo(name="hello",defaultPhase = LifecyclePhase.CLEAN)
public class MyMojo extends AbstractMojo
{
     // 配置的是本maven插件的配置,在pom使用configration标签进行配置 property就是名字,
    @Parameter
    private String test;

    public void execute() throws MojoExecutionException {
       System.out.println(" ---------->> Hello My Plugins = " + test);
    }
}

3、 把这个插件,安装到库里面,执行 mvn install。其他项目的pom,在其他项目引用这个插件就像平常一样,在build里面写上插件的信息。

<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.test.maven.phase</groupId>
  <artifactId>my-maven-test-phase</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  
  <build>
      <plugins>
      <plugin>
        <groupId>com.test.maven</groupId>
        <artifactId>my-maven-plugin</artifactId>
        <version>1.0-SNAPSHOT</version>
        <configuration>
            <test>peter</test>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

4、运行

这里的hello对应的就是上面我们自定义组件中@Mojo里面的name属性:

mvn my:hello
Maven快照和版本的区别

快照是一种特殊的版本,指定了某个当前的开发进度的副本。不同于常规的版本,Maven 每次构建都会在远程仓库中检查新的快照。 现在 data-service 团队会每次发布更新代码的快照到仓库中,比如说 data-service:1.0-SNAPSHOT 来替代旧的快照 jar 包。

对于版本,如果 Maven 以前下载过指定的版本文件,比如说 data-service:1.0,Maven 将不会再从仓库下载新的可用的 1.0 文件。若要下载更新的代码,data-service 的版本需要升到1.1。

快照的情况下,每次 app-ui 团队构建他们的项目时,Maven 将自动获取最新的快照(data-service:1.0-SNAPSHOT)。

写在最后

好啦,以上就是强哥为大家整理的Maven相关的知识点,当然有一些非常基础我们平常都在用的强哥就没列进去了。即使不是用于面试,这个文档还是很值得收藏的。之后还会总结一些其他面试的相关资料,大家敬请期待哈~

分类:

后端

标签:

后端

作者介绍

强哥叨逼叨
V1

欢迎关注公众号:强哥叨逼叨