Maven专题(一) - Maven基础

一、坐标定义

<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.ioteye.maven</groupId>
	<artifactId>maven</artifactId>
	<version>1.0.0</version>
	<packaging>pom</packaging>
	<name>maven</name>
	<url>http://maven.apache.org</url>
</project>
  • packaging
    maven项目的打包方式
  • classifier
    用来帮助定义构建输出的一些附属构件,如javadoc或sources。
    注意,不能直接定义项目的classifier,因为附属构件不是项目直接默认生成的,而是由附加的插件帮助生成的。

二、依赖配置

pom.xml中dependencies标签下包含一个或多个dependence元素,用来声明一个或多个项目依赖。

<dependencies>
	<dependency>
		<groupId>junit</groupId>
		<artifactId>junit</artifactId>
		<version>4.12</version>
		<scope>test</scope>
	</dependency>
</dependencies>
  • type:依赖的类型,对应项目坐标的packaging
  • scope:依赖范围
  • optional
    应用场景:A 依赖B, B依赖C。
    当B的optional=true时,A中如果没有显式引入C,则A不依赖C,即A可以自己选择是否依赖C。
    默认optional=false,子项目必须依赖。
  • exclusions:用来排除传递性依赖

三、依赖范围

compile:scope默认依赖范围,对于编译,测试,运行三种classpath都有效,如spring-core
test:只对于测试classpath有效,如JUnit
provided:对编译和测试classpath有效,运行时无效。如servlet-api,因为运行时容器已经提供,不需要maven重复引入
runtime:测试和运行时classpath有效如JDBC驱动实现,编译时只需要JDK提供的JDBC接口
system:同provided范围一致,使用system范围的依赖不是通过maven仓库解析,而是通过systemPath元素显示指定依赖文件。因为可能造成构建的不可移植,应谨慎使用。

四、依赖传递

如果项目的依赖有自己的依赖,则项目也会加载依赖的依赖。比如spring-core依赖commons-logging,如果项目依赖了spring-core,那么它也会依赖commons-logging。当依赖的声明为可选时(true),依赖不会传递。

五、依赖调解

因为存在依赖传递,就会有不同的依赖中有不同版本的基础依赖,如A -> X(1.0),B -> C -> X(2.0),这样X就有不同的版本,哪个会被maven解析呢?于是就有了依赖调解的两个原则:

路径最近者优。,如上X(1.0)的路径为1,而X(2.0)的路径为2,因此X(1.0)会被使用
同等路径下,第一声明者优先。在路径长度都一致时,pom.xml中顺序靠前的被使用。

六、依赖排除

项目中可能存在,因为一些原因,不想引入某依赖的传递性依赖,则可以使用exclusions。比如在使用spring时不想用commons-logging,则可以在spring-core中排除。

<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-core</artifactId>
	<version>5.0.0.M5</version>
	<exclusions>
		<exclusion>
			<groupId>commons-logging</groupId>
			<artifactId>commons-logging</artifactId>
		</exclusion>
	</exclusions>
</dependency>

七、依赖版本归类

比如在使用spring时,可能会用到spring-context,spring-jdbc,spring-tx等,但他们的版本是一致的,考虑到以后版本的升级,可以定义一个spring.version的properties来统一设置版本。

<properties>
    <spring.version>4.1.6.RELEASE</spring.version>
</properties>

而在依赖的中用${spring.version}代替

<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-context</artifactId>
	<version>${spring.version}</version>
</dependency>
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-jdbc</artifactId>
	<version>${spring.version}</version>
</dependency>
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-tx</artifactId>
	<version>${spring.version}</version>
</dependency>

八、依赖查看与分析

// 查看项目依赖列表
mvn dependency:list
// 以树状显示依赖列表
mvn dependency:tree
// 依赖分析
mvn dependency:analyze

九、生命周期

maven有三套相互独立的生命周期,分别是clean,default,site。

  • clean:清理项目
  • default:构建项目
  • site:建立项目站点

每个生命周期包含一些阶段(phase),这些阶段是有顺序的,并且后面的阶段依赖于前面的阶段。default是生命周期中最核心的部分,它包含很多阶段,以下是常见的几种阶段,全量的阶段可见http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html#Lifecycle_Reference。

  • validate:验证项目是否正确
  • compile:编译项目源代码
  • test:使用一个测试套件测试编译后的代码
  • package:打包项目代码
  • verify:检查集成测试结果
  • install:将打包好的项目代码安装到本地仓库
  • deploy:复制最后的打包结果到远程仓库

我们可以用命令行来执行生命周期阶段

  • mvn clean:调用clean生命周期的clean阶段,包含pre-clean和clean阶段
  • mvn test:调用default生命周期的test阶段,包含validate到test的所有阶段
  • mvn clean install:调用clean生命周期的clean阶段和default生命周期的install阶段,实际执行的是clean生命周期的pre-clean,clean阶段和default生命周期从validate至install的所有阶段

十、多环境配置

如果需要针对不同环境配置环境变量,那么可以通过profiles实现。

<profiles>
    <profile>
        <id>test</id>
        <!-- 环境变量 -->
        <properties>
            <env.name>test</env.name>
            <env.version>snapshot</env.version>
        </properties>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
    </profile>
    <profile>
        <id>prd</id>
        <properties>
            <env.name>prd</env.name>
            <env.version>bin</env.version>
        </properties>
    </profile>
</profiles>

<build>
   <resources>
		<resource>
			<directory>src/main/resources</directory>
			<excludes>
				<exclude>dev/*</exclude>
				<exclude>prd/*</exclude>
			</excludes>
		</resource>
		<resource>
			<directory>${project.basedir}/src/main/resources/${env.name}</directory>
			<filtering>true</filtering>
		</resource>
	</resources>
</build>

十一、插件

11.1 插件目标

我们知道maven的核心只定义了抽象的生命周期,具体的任务是交由插件完成的,插件以独立的构件存在,maven会在需要时下载并使用插件。对于一个插件,可能会有多个功能,每个功能就对应一个插件目标(Plugin Goal)。

比如maven-dependency-plugin有多个目标,如dependency:list,dependency:tree,dependency:analyze等,冒号前是插件前缀,冒号后是插件目标。类似的,compiler:compile(maven-compiler-plugin的compile目标)和surefire:test(maven-surefire-plugin的test目标)。

在使用时,需要将生命周期的阶段和插件目标相互绑定,以完成某个具体的构建任务。如maven-compiler-plugin的compile目标绑定的就是default生命周期的compile阶段。

maven内置了很多生命周期阶段同插件目标的绑定,比如打包类型为jar的default生命周期的内置插件绑定关系如下:

生命周期阶段插件目标执行任务
process-resourcesmaven-resources-plugin:resources复制主资源文件至主输出目录
compilemaven-compiler-plugin:compile编译主代码至主输出目录
process-test-resourcesmaven-resources-plugin:testResources复制测试资源文件至测试输出目录
test-compilemaven-compiler-plugin:testCompile编译测试代码至测试输出目录
testmaven-surefire-plugin:test执行测试用例
packagemaven-jar-plugin:jar创建项目jar包
installmaven-install-plugin:install将项目输出构件安装到本地仓库
deploymaven-deploy-plugin:deploy将项目输出构件部署到远程仓库

除了内置的绑定关系外,用户可以选择将某个插件目标绑定到生命周期的某个阶段。一个例子是创建项目的源码jar包,可以使用maven-source-plugin的jar-no-fork目标将项目主代码打成jar文件,我们将其绑定到verify阶段。

<plugin>
	<groupId>org.apache.maven.plugins</groupId>
	<artifactId>maven-source-plugin</artifactId>
	<version>3.0.1</version>
	<executions>
		<execution>
			<id>attach-sources</id>
			<phase>verify</phase>
			<goals>
				<goal>jar-no-fork</goal>
			</goals>
		</execution>
	</executions>
</plugin>

有很多插件的目标在编写时已经定义了默认绑定阶段,可以使用命令查看。

mvn help:describe -Dplugin=org.apache.maven.plugins:maven-source-plugin:3.0.1 -Ddetail

可以看到输出的信息中有。

source:jar-no-fork
...
Bound to phase: package

即jar-no-for默认绑定的生命周期阶段为package。

11.2 插件配置

用户可以通过命令行和pom配置来配置插件的参数

  1. 命令行配置,用户可以在maven命令中使用-D参数,指定一个key-value的形式,来配置插件目标的参数。例如maven-surefire-plugin提供了一个maven.test.skip参数,当为true时,就跳过执行测试。
mvn install -Dmaven.test.skip=true
  1. pom中插件全局配置,所有基于该插件目标的任务都会使用此配置,常见的maven-compiler-plugin编译java的版本。
<plugin>
	<groupId>org.apache.maven.plugins</groupId>
	<artifactId>maven-compiler-plugin</artifactId>
	<version>2.3.2</version>
	<configuration>
		<source>1.8</source>
		<target>1.8</target>
		<encoding>utf-8</encoding>
	</configuration>
</plugin>
  1. 用户可以为某个插件任务配置特定的参数,将maven-antrun-plugin:run绑定到多个生命周期阶段上,加以不同的配置。
<plugin>
	<artifactId>maven-antrun-plugin</artifactId>
	<version>1.8</version>
	<executions>
		<execution>
			<id>ant-validate</id>
			<phase>validate</phase>
			<goals>
				<goal>run</goal>
			</goals>
			<configuration>
				<tasks>
					<echo>validate phase</echo>
				</tasks>
			</configuration>
		</execution>
		<execution>
			<id>ant-verify</id>
			<phase>verify</phase>
			<goals>
				<goal>run</goal>
			</goals>
			<configuration>
				<tasks>
					<echo>verify phase</echo>
				</tasks>
			</configuration>
		</execution>
	</executions>
</plugin>

11.3 插件查找

可以从http://maven.apache.org/plugins/index.html中查询插件的详细信息,也可以使用maven-help-plugin描述插件。

// 查询插件信息
mvn help:describe -Dplugin=org.apache.maven.plugins:maven-source-plugin:3.0.1
// 查询插件目标信息
mvn help:describe -Dplugin=org.apache.maven.plugins:maven-source-plugin:3.0.1 -Dgoal=jar-no-fork
// 查询详细信息
mvn help:describe -Dplugin=org.apache.maven.plugins:maven-source-plugin:3.0.1 -Ddetail

十二、Maven内置变量

Maven内置了一些目录变量,对涉及文件路径的配置会有帮助、

${basedir} 项目根目录
${project.build.directory} 构建目录,缺省为target
${project.build.outputDirectory} 构建过程输出目录,缺省为target/classes
${project.build.finalName} 产出物名称,缺省为${project.artifactId}-${project.version}
${project.packaging} 打包类型,缺省为jar
${project.xxx} 当前pom文件任意节点的内容
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值