哈喽,大家好,我是强哥。
现在正值金三银四的好时节,面试前的准备必然不能少,毕竟一次好的面试准备对于是否能找到好的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>
那么在子模块中只需要groupId
和artifactId
即可,如:
<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相关的知识点,当然有一些非常基础我们平常都在用的强哥就没列进去了。即使不是用于面试,这个文档还是很值得收藏的。之后还会总结一些其他面试的相关资料,大家敬请期待哈~