什么是Maven仓库
在不用Maven的时候,比如说以前我们用Ant构建项目,在项目目录下,往往会看到一个名为/lib的子目录,那里存放着各类第三方依赖jar文件,如log4j.jar,junit.jar等等。每建立一个项目,你都需要建立这样的一个/lib目录,然后复制一对jar文件,这是很明显的重复。重复永远是噩梦的起点,多个项目不共用相同的jar文件,不仅会造成磁盘资源的浪费,也使得版本的一致性管理变得困难。此外,如果你使用版本管理工具,如SVN(你没有使用版本管理工具?马上试试SVN吧,它能帮你解决很多头疼的问题),你需要将大量的jar文件提交到代码库里,可是版本管理工具在处理二进制文件方面并不出色。
Maven仓库就是放置所有JAR文件(WAR,ZIP,POM等等)的地方,所有Maven项目可以从同一个Maven仓库中获取自己所需要的依赖JAR,这节省了磁盘资源。此外,由于Maven仓库中所有的JAR都有其自己的坐标,该坐标告诉Maven它的组ID,构件ID,版本,打包方式等等,因此Maven项目可以方便的进行依赖版本管理。你也不在需要提交JAR文件到SCM仓库中,你可以建立一个组织层次的Maven仓库,供所有成员使用。
简言之,Maven仓库能帮助我们管理构件(主要是JAR)。
环境准备
官方下载地址: http://maven.apache.org/download.cgi
Windows安装
下载安装包apache-maven-3.5.4-bin.zip
解压到指定目录例如 C:\Program Files\Java\maven
添加环境变量
# 添加HOME和PATH
MAVEN_HOME=C:\maven3.6.1
PATH=C:\maven3.6.1\bin
Linux安装
# 上传到节点指定目录,添加环境变量:
export MAVEN_HOME=/opt/apache-maven-3.5.4
export PATH=${PATH}:${MAVEN_HOME}/bin
其他内容
M2_HOME = C:\Program Files\Java\apache-maven-3.5.0\bin
MAVEN_OPTS = -Xms128m -Xmx512m
自动下载的jar包一般存放在:位于 C:\Users\用户名.m2 目录。
使用中国源
编译maven项目时,会下载很多maven的插件,如果什么都没做的话,就会从默认的官网仓库地址下载。
为了加快访问速度,我们要把官网仓库地址替换为国内访问速度较快的镜像地址。
http://maven.aliyun.com/nexus/content/groups/public/
方法一
在settings.xml中找到,如下内容,将中央仓库(central)的默认地址设置为阿里云的地址。
<mirrors>
<!-- mirror
| Specifies a repository mirror site to use instead of a given repository. The repository that
| this mirror serves has an ID that matches the mirrorOf element of this mirror. IDs are used
| for inheritance and direct lookup purposes, and must be unique across the set of mirrors.
|
<mirror>
<id>mirrorId</id>
<mirrorOf>repositoryId</mirrorOf>
<name>Human Readable Name for this Mirror.</name>
<url>http://my.repository.com/repo/path</url>
</mirror>
-->
<mirror>
<id>mirrorId</id>
<mirrorOf>central</mirrorOf>
<name>Human Readable Name for this Mirror.</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
</mirror>
</mirrors>
方法二:直接在项目的pom.xml上改
<repositories>
<repository>
<id>aliyun</id>
<name>aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<layout>default</layout>
<releases>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>aliyun</id>
<name>aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
配置pom.xml
<project>
<groupId>com.oreilly.learningsparkexamples.mini</groupId>
<artifactId>learning-spark-mini-example</artifactId>
<modelVersion>4.0.0</modelVersion> <!--pom模型版本,maven2和3只能为4.0.0-->
<name>example</name> <!--???-->
<!-- 基本配置 -->
<groupId>com.rexen.test</groupId> <!--组ID,maven用于定位-->
<artifactId>Test</artifactId> <!--组中唯一ID,maven用于定位-->
<version>1.0-SNAPSHOT</version> <!--版本号-->
<packaging>jar</packaging> <!--打包方式 如:pom, jar, maven-plugin, ejb, war, ear, rar, par-->
<!-- 用于定义pom常量 -->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spark.version>2.2.0</spark.version> <!-- 这个常量可以在pom文件的任意地方通过${spark.version}来引用 -->
<scala.version>2.10</scala.version>
<hadoop.version>2.6.0</hadoop.version>
</properties>
<!-- 依赖配置 -->
<repositories>
<repository>
<id>jboss</id>
<name>Maven of jboss.org</name>
<url>http://repository.jboss.org/nexus/content/groups/public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
<layout>default</layout>
</repository>
</repositories>
<!-- 依赖配置 用于确定父项目的坐标 -->
<parent>
<groupId>com.rexen.learn</groupId> <!--父项目的构件标识符-->
<artifactId>test-parent</artifactId> <!--父项目的唯一标识符-->
<relativePath></relativePath> <!--Maven首先在当前项目的找父项目的pom,在文件系统的这个位置(relativePath),后在本地仓库,最后在远程仓库找。-->
<version>1.1-SNAPSHOT</version> <!--父项目的版本-->
</parent>
<!-- 有些maven项目会做成多模块的,这个标签用于指定当前项目所包含的所有模块。之后对这个项目进行的maven操作,会让所有子模块也进行相同操作 -->
<modules>
<module>com-a</module>
<module>com-b</module>
<module>com-c</module>
</modules>
<!-- 项目相关依赖配置,如果在父项目写的依赖,会被子项目引用,一般父项目会将子项目公用的依赖引入,这边依赖和中央仓库中的一致,就可以引入对应的jar -->
<dependencies>
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_2.10</artifactId>
<version>1.6.3</version>
</dependency>
</dependencies>
<!-- 配置写法同dependencies -->
<dependencyManagement>...</dependencyManagement>
<!-- 插入样例 在父模块中定义后,子模块不会直接使用对应依赖,但是在使用相同依赖的时候可以不加版本号,好处是,父项目统一了版本,而且子项目可以在需要的时候才引用对应的依赖
父项目:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement>
子项目:
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
-->
<!-- 构建配置 -->
<build>
<sourceDirectory>src/main</sourceDirectory> <!--该元素设置了项目源码目录,当构建项目的时候,构建系统会编译目录里的源码。该路径是相对于pom.xml的相对路径。-->
<scriptSourceDirectory/> <!--该元素设置了项目脚本源码目录,该目录和源码目录不同:绝大多数情况下,该目录下的内容 会被拷贝到输出目录(因为脚本是被解释的,而不是被编译的)。-->
<testSourceDirectory/> <!--该元素设置了项目单元测试使用的源码目录,当测试项目的时候,构建系统会编译目录里的源码。该路径是相对于pom.xml的相对路径。-->
<outputDirectory/> <!--被编译过的应用程序class文件存放的目录。-->
<testOutputDirectory/> <!--被编译过的测试class文件存放的目录。-->
<extensions> <!--使用来自该项目的一系列构建扩展-->
<extension> <!--描述使用到的构建扩展。-->
<groupId/> <!--构建扩展的groupId-->
<artifactId/> <!--构建扩展的artifactId-->
<version/> <!--构建扩展的版本-->
</extension>
</extensions>
<defaultGoal/> <!--当项目没有规定目标(Maven2 叫做阶段)时的默认值-->
<resources> <!--这个元素描述了项目相关的所有资源路径列表,例如和项目相关的属性文件,这些资源被包含在最终的打包文件里。-->
<resource> <!--这个元素描述了项目相关或测试相关的所有资源路径-->
<targetPath/> <!-- 描述了资源的目标路径。该路径相对target/classes目录(例如${project.build.outputDirectory})。
举个例 子,如果你想资源在特定的包里(org.apache.maven.messages),你就必须该元素设置为org/apache/maven /messages。然而,如果你只是想把资源放到源码目录结构里,就不需要该配置。-->
<filtering>true</filtering> <!--是否使用参数值代替参数名。参数值取自properties元素或者文件里配置的属性,文件在filters元素里列出。-->
<directory>src/main/java</directory> <!--描述存放资源的目录,该路径相对POM路径-->
<includes> <!--包含的模式列表,例如**/*.xml.-->
<include>*.*</include>
</includes>
<excludes/> <!--排除的模式列表,例如**/*.xml-->
</resource>
</resources>
<testResources> <!--这个元素描述了单元测试相关的所有资源路径,例如和单元测试相关的属性文件。-->
<testResource>
<targetPath/> <!--这个元素描述了测试相关的所有资源路径,参见build/resources/resource元素的说明-->
<filtering/>
<directory/>
<includes/>
<excludes/>
</testResource>
</testResources>
<directory/> <!--构建产生的所有文件存放的目录-->
<finalName/> <!--产生的构件的文件名,默认值是${artifactId}-${version}。-->
<filters/> <!--当filtering开关打开时,使用到的过滤器属性文件列表-->
<pluginManagement> <!--子项目可以引用的默认插件信息。该插件配置项直到被引用时才会被解析或绑定到生命周期。给定插件的任何本地配置都会覆盖这里的配置-->
<plugins> <!--使用的插件列表 。-->
<plugin> <!--plugin元素包含描述插件所需要的信息。-->
<groupId/> <!--插件在仓库里的group ID-->
<artifactId/><!--插件在仓库里的artifact ID-->
<version/><!--被使用的插件的版本(或版本范围)-->
<extensions/><!--是否从该插件下载Maven扩展(例如打包和类型处理器),由于性能原因,只有在真需要下载时,该元素才被设置成enabled。-->
<executions><!--在构建生命周期中执行一组目标的配置。每个目标可能有不同的配置。-->
<execution><!--execution元素包含了插件执行需要的信息-->
<id/><!--执行目标的标识符,用于标识构建过程中的目标,或者匹配继承过程中需要合并的执行目标-->
<phase/><!--绑定了目标的构建生命周期阶段,如果省略,目标会被绑定到源数据里配置的默认阶段-->
<goals/><!--配置的执行目标-->
<inherited/><!--配置是否被传播到子POM-->
<configuration/><!--作为DOM对象的配置-->
</execution>
</executions>
<dependencies><!--项目引入插件所需要的额外依赖-->
<dependency><!--参见dependencies/dependency元素-->
</dependency>
</dependencies>
<inherited/><!--任何配置是否被传播到子项目-->
<configuration/><!--作为DOM对象的配置-->
</plugin>
</plugins>
</pluginManagement>
<plugins> <!--使用的插件列表-->
<plugin>
<!-- 这是个编译java代码的 -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.2</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
<encoding>UTF-8</encoding>
</configuration>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<!-- 这是个编译scala代码的 -->
<groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId>
<version>3.2.1</version>
<executions>
<execution>
<id>scala-compile-first</id>
<phase>process-resources</phase>
<goals>
<goal>add-source</goal>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.oreilly.learningsparkexamples.mini.scala.WordCount</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<reporting> <!--该元素描述使用报表插件产生报表的规范。当用户执行“mvn site”,这些报表就会运行。 在页面导航栏能看到所有报表的链接。-->
<excludeDefaults/><!--true,则,网站不包括默认的报表。这包括“项目信息”菜单中的报表。-->
<outputDirectory/><!--所有产生的报表存放到哪里。默认值是${project.build.directory}/site。-->
<plugins><!--使用的报表插件和他们的配置。-->
<plugin><!--plugin元素包含描述报表插件需要的信息-->
<groupId/><!--报表插件在仓库里的group ID-->
<artifactId/><!--报表插件在仓库里的artifact ID-->
<version/><!--被使用的报表插件的版本(或版本范围)-->
<inherited/><!--任何配置是否被传播到子项目-->
<configuration/><!--报表插件的配置-->
<reportSets><!--一组报表的多重规范,每个规范可能有不同的配置。一个规范(报表集)对应一个执行目标 。例如,有1,2,3,4,5,6,7,8,9个报表。1,2,5构成A报表集,对应一个执行目标。2,5,8构成B报表集,对应另一个执行目标-->
<reportSet><!--表示报表的一个集合,以及产生该集合的配置-->
<id/><!--报表集合的唯一标识符,POM继承时用到-->
<configuration/><!--产生报表集合时,被使用的报表的配置-->
<inherited/><!--配置是否被继承到子POMs-->
<reports/><!--这个集合里使用到哪些报表-->
</reportSet>
</reportSets>
</plugin>
</plugins>
</reporting>
</project>
参考文档
http://www.yiibai.com/maven/
http://mvnrepository.com/
http://maven.apache.org/pom.html