maven教程
maven是什么?
maven是一个项目管理工具, 它包含了一个项目对象模型(Project Object Model),一组标准集合,一个项目声明周期(Project Lifecycle),一个依赖管理系统(Dependency Management System),和用来运行定义在生命周期阶段(phase)中插件(plugin)目标(goal)的逻辑。
maven是面向技术层面的,针对java开发项目管理工具,它提供了构建工具所提供功能的超集,除构建功能外,maven还可以管理项目结构、管理依赖关系、生成报告、生成web站点、有助于团队成员之间的交流与协作。
为什么使用maven?
- 指导开发。
- 自动编译。
- 依赖管理。
- 无限扩展。
- 持续集成。
- 开发协作。
怎么使用maven?
官网下载安装
- 地址
- 解压安装
在window下直接使用压缩工具解压。
在linux使用 tar -zxvf **.tar.gz 方式解压。
进入项目根目录,读取readme.txt文件。
- 配置环境变量
Unix-based operating systems (Linux, Solaris and Mac OS X)
export PATH=/usr/local/apache-maven-3.x.y/bin:$PATH
Windows
set PATH="c:\program files\apache-maven-3.x.y\bin";%PATH%
建议配置M2_HOME,再配置path路径 * 运行mvn -version检查是否安装成功?
mvn -v
Apache Maven 3.0.4 (r1232337; 2012-01-17 16:44:56+0800)
Maven home: G:\tool\apache-maven-3.0.4-bin\apache-maven-3.0.4\bin\.
Java version: 1.8.0_20, vendor: Oracle Corporation
Java home: G:\tool\Java\jdk1.8.0_20\jre
Default locale: zh_CN, platform encoding: GBK
OS name: "windows 7", version: "6.1", arch: "amd64", family: "dos"
#### maven的目录结构
bin
boot
conf
lib
LICENSE
NOTICE
README.TXT
LICENSE主要时maven的许可证协议描述。
NOTICE maven的版权信息以及官方地址。
README.TXT 包含了maven安装的详细步骤和介绍。
bin maven的运行脚本
boot 包含了一个负责创建maven运行所需要的类装载器的jar文件。
conf目录 包含了一个全局的settings.xml配置文件,该文件用于自定义你机器上的maven的一些行为。一般我们是在~/.m2目录覆写settings.xml。
lib maven运行时所需要的类库
#### 使用maven创建第一个项目 * java普通项目
mvn archetype:generate -DgroupId=${groupId} -DartifactId=${artifacetId}
-Dversion=${version} -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
groupId: 组织名称
artifactId: 项目名称
version: 版本号
例子
mvn archetype:generate -DgroupId=com.hunantv -DartifactId=oss -Dversion=0.1.1 -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
interactiveMode 用户输入进行交互,默认true,可以使用mvn -B简化操作
目录结构:
-oss
--src
---main
----java
-----com
------hunantv
---test
----java
-----com
------hunantv
* java web项目创建
mvn archetype:generate -DgroupId=${groupId} -DartifactId=${artifacetId}
-Dversion=${version} -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
groupId: 组织名称
artifactId: 项目名称
version: 版本号
例子
mvn archetype:generate -DgroupId=com.hunantv -DartifactId=ossweb -Dversion=0.1.1 -DarchetypeArtifactId=maven-archetype-webapp -DinteractiveMode=false
目录结构
-ossweb
--src
---main
----resources
-----com
-----webapp
------WEB-INF
* android 项目创建 * 后面会说,怎么创建自己的基础项目 #### 讲解maven的目录结构 * java普通项目
-project
--src
---main
----resources
----filters
----assembly
----java
---test
----resources
----java
src
main 项目主体目录
resources 常用配置文件目录,比如properties以及xml
java java源码
filters 资源过滤目录
assembly asssembly描述
config 配置文件根目录
test 项目测试根目录
resources 测试的配置文件目录
java 测试源码目录
filters 测试过滤目录
target 输出根目录
classes 项目主体输出目录
test-classes 项目测试输出目录
site 项目站点目录
* java web项目
-project
--src
---main
----java
----resources
----webapp
----WEB-INF
---test
----java
----resources
#### maven 生命周期 * 生命周期组成 1. clean生命周期。 2. default生命周期 3. site生命周期 * 组成maven单个生命周期的元素 1. clean 包括pre-clean 、clean 、 post-clean 2. default 包括 compile、test、package、install、deploy default生命周期是最核心的,它包含了构建项目时真正需要执行的所有步骤。
validate 验证项目是否正确,以及所有为了完整构建必要的信息是否可用
initialize
generate-sources 生成所有需要包含在编译过程中的源代码
process-sources 处理源代码,比如过滤一些值
generate-resources 生成所有需要包含在打包过程中的资源文件
process-resources :复制和处理资源文件到target目录,准备打包;
compile :编译项目的源代码;
process-classes 后处理编译生成的文件,例如对Java类进行字节码增强(bytecode enhancement)
generate-test-sources 生成所有包含在测试编译过程中的测试源码
process-test-sources 处理测试源码,比如过滤一些值
generate-test-resources 生成测试需要的资源文件
process-test-resources 复制并处理测试资源文件至测试目标目录
test-compile :编译测试源代码;
process-test-classes
test :运行测试代码;
prepare-package 在真正的打包之前,执行一些准备打包必要的操作
package :打包成jar或者war或者其他格式的分发包;
pre-integration-test 执行一些在集成测试运行之前需要的动作。如建立集成测试需要的环境
integration-test 如果有必要的话,处理包并发布至集成测试可以运行的环境
post-integration-test 执行一些在集成测试运行之后需要的动作。如清理集成测试环境。
verify 执行所有检查,验证包是有效的,符合质量规范
install :将打好的包安装到本地仓库,供其他项目使用;
deploy :将打好的包安装到远程仓库,供其他项目使用;
3. site 包括 pre-site、site、post-site、site-deploy #### 使用ide工具构建maven项目 * 需要输入的参数。 * 新建类 * 新建配置文件 * 新建测试类 * 运行测试 * 添加依赖jar包 * 指定编译器版本 * 指定编译器源码 * 打包 * 运行helloworld #### maven架构图和原理 * 架构图
采用远程仓库和本地仓库,类似一个build.xml的pom.xml,将pom.xml中定义的jar文件从远程仓库下载到本地仓库,各个应用使用同一个本地仓库的jar,同一个版本的jar只会下载一次,而且避免每个应用去拷贝jar。
- pom.xml 文档描述
<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>
<!-- The Basics -->
<groupId>...</groupId>
<artifactId>...</artifactId>
<version>...</version>
<packaging>...</packaging>
<dependencies>...</dependencies>
<parent>...</parent>
<dependencyManagement>...</dependencyManagement>
<modules>...</modules>
<properties>...</properties>
<!-- Build Settings -->
<build>...</build>
<reporting>...</reporting>
<!-- More Project Information -->
<name>...</name>
<description>...</description>
<url>...</url>
<inceptionYear>...</inceptionYear>
<licenses>...</licenses>
<organization>...</organization>
<developers>...</developers>
<contributors>...</contributors>
<!-- Environment Settings -->
<issueManagement>...</issueManagement>
<ciManagement>...</ciManagement>
<mailingLists>...</mailingLists>
<scm>...</scm>
<prerequisites>...</prerequisites>
<repositories>...</repositories>
<pluginRepositories>...</pluginRepositories>
<distributionManagement>...</distributionManagement>
<profiles>...</profiles>
</project>
project
groupId #required 是一个唯一的组织或者工程,例如所有的maven项目都在org.apache.maven
artifactId #required 一般是项目的名称。
version #required 版本号
packaging 项目打包方式 值可以有pom,jar,maven-plugin,ejb,war,ear,rar,par等。
classifier 该元素帮助定义构建输出的一些附件。
optional: 标记依赖是否可选
scope: 依赖的范围,下面会进行详解
exclusions: 用来排除传递性依赖,下面会进行详解
scope | 编译期 | 测试期 | 运行期 | 说明 |
---|---|---|---|---|
compile | √ | √ | √ | 默认scope ,具有依赖传递性 |
test | √ | 只在测试期间依赖,如junit包 | ||
provided | √ | √ | 运行期间由容器提供,比如servlet-api | |
runtime | √ | √ | 编译期间不用直接引用 | |
system | √ | √ | 编译和测试时由本机环境提供 |
settings.xml 文档配置
<settings>
<!--个人本地仓库地址-->
<mirrors>
<mirror>
<id>nexus-public-group</id>
<name>hunantv-nexus-repositories</name>
<url>http://192.168.1.121:8881/nexus/content/groups/hunantv-group/</url>
<mirrorOf>*</mirrorOf>
</mirror>
</mirrors>
<profiles>
<profile>
<id>development</id>
<repositories>
<repository>
<id>hunantv-nexus-public-group</id>
<url>http://central</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy><!--依赖包发布后,不用每次都更新版本号-->
<checksumPolicy>warn</checksumPolicy>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>hunantv-nexus-public-group</id>
<url>http://central</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</profile>
</profiles>
<activeProfiles>
<activeProfile>development</activeProfile>
</activeProfiles>
<servers>
<server>
<id>hunantv-releases</id>
<username>deployment</username>
<password>deployment123</password>
</server>
<server>
<id>hunantv-snapshots</id>
<username>deployment</username>
<password>deployment123</password>
</server>
</servers>
</settings>
<mirrorOf>*</mirrorOf> 匹配所有远程仓库。 这样所有pom中定义的仓库都不生效
<mirrorOf>external:*</mirrorOf> 匹配所有远程仓库,使用localhost的除外,使用file://协议的除外。也就是说,匹配所有不在本机上的远程仓库
<mirrorOf>repo1,repo2</mirrorOf> 匹配仓库repo1和repo2,使用逗号分隔多个远程仓库。
<mirrorOf>*,!repo1</miiroOf> 匹配所有远程仓库,repo1除外,使用感叹号将仓库从匹配中排除。
nexus 带过说一下。
maven常用插件
查看插件目标详情列子
mvn spring-boot:help -Ddetail=true -Dgoal=repackage
spring-boot是插件,冒号后面是目标.
- clean 插件
maven内置插件
- resource 插件
执行阶段 process-resources maven内置插件
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.7</version>
<configuration>
...
<encoding>UTF-8</encoding>
...
</configuration>
</plugin>
默认resources是在工程src/main/resources
可以自定义目录
<project>
...
<build>
...
<resources>
<resource>
<directory>resource1</directory>
</resource>
<resource>
<directory>resource2</directory>
</resource>
<resource>
<directory>resource3</directory>
</resource>
</resources>
...
</build>
...
</project>
如果资源文件目录中有其他二进制文件,请使用如下:
<project>
...
<build>
...
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<filtering>false</filtering>
<excludes>
<exclude>**/*.xml</exclude>
</excludes>
</resource>
...
</resources>
...
</build>
...
</project>
- 编译插件
Apache Maven Compiler Plugin
maven内置插件
<project>
[...]
<build>
[...]
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
</plugins>
[...]
</build>
[...]
</project>
- jar插件
Apache Maven JAR Plugin
maven内置插件
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.1</version>
<!--jar 中main类描述-->
<configuration>
<archive>
<manifest>
<mainClass>com.hunantv.liveshow.LiveShowServer</mainClass>
<addClasspath>true</addClasspath>
<classpathPrefix>lib</classpathPrefix>
</manifest>
</archive>
</configuration>
</plugin>
- 源码插件
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.2.1</version>
<executions>
<execution>
<id>attach-source</id>
<phase>verify</phase><!-- 要绑定到的生命周期的阶段 -->
<goals>
<goal>jar-no-fork</goal><!-- 要绑定的插件的目标 -->
</goals>
</execution>
</executions>
</plugin>
- assember 打包插件
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<!--打包时,不带上assembly配置文件中的id名称-->
<appendAssemblyId>false</appendAssemblyId>
<descriptor>assembly.xml</descriptor>
<outputDirectory>target</outputDirectory>
<workDirectory>target</workDirectory>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals> <goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
assembly文件配置
<assembly>
<id>withDependencies</id>
<formats>
<format>dir</format>
</formats>
<includeBaseDirectory>true</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>target</directory>
<outputDirectory></outputDirectory>
<includes>
<include>*.jar</include>
</includes>
</fileSet>
<fileSet>
<directory>.</directory>
<outputDirectory>
</outputDirectory>
<includes>
<include>confs/*.*</include>
<include>*.sh</include>
<include>*.bat</include>
</includes>
</fileSet>
</fileSets>
<dependencySets>
<dependencySet>
<outputDirectory>lib</outputDirectory>
<scope>runtime</scope>
<!--排除自身-->
<useProjectArtifact>false</useProjectArtifact>
</dependencySet>
</dependencySets>
</assembly>
format 支持
zip 、tar、tar.gz、tar.brz、jar、dir、war.
includeBaseDirectory 默认true 会在打包的时候,将项目目录打包在压缩文件中,建议设置为false
fileSet 相对于当前目录的位置
dependencySet 相对输出的根目录的目录
<dependencies>
[...]
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
[...]
</dependencies>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.18.1</version>
<dependencies>
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-junit47</artifactId>
<version>2.18.1</version>
</dependency>
</dependencies>
</plugin>
[...]
- 环境配置插件
<plugin>
<groupId>com.juvenxu.portable-config-maven-plugin</groupId>
<artifactId>portable-config-maven-plugin</artifactId>
<version>1.1.5</version>
<executions>
<execution>
<goals>
<goal>replace-package</goal>
</goals>
</execution>
</executions>
<configuration>
<portableConfig>src/main/portable/test.xml</portableConfig>
</configuration>
</plugin>
注意:
此操作是在打包代码完成后,进行修改。建议此插件放在所有的插件后面声明。
- 构建插件
maven高级部分
- 依赖详解
依赖调解
传递路径长度取最短原则,传递路径长度相等时,采取最先申明原则
传递依赖
jar包中的compile范围的依赖是可以相互传递的.
可选依赖
尽量少用,可选依赖不会被传递,需要显式申明
排除依赖
发现依赖包里有些包不稳定,可以排除依赖,显式的申明文档的包
依赖归类
当同一个模块,所依赖的几个模块版本都相同时,可以使用maven里的属性做分类依赖,依赖版本升级时改一处即可
优化依赖
mvn dependency:list
mvn dependency:tree
mvn dependency:analyze
- 多模块项目
消除多模块依赖配置重复
<dependencyManagement>
消除多模块插件配置重复
<pluginManagement>
- pom.xml继承
maven结合工具使用常碰到的一些问题。
nexus 使用
- 下载安装
http://www.sonatype.org/nexus/thank-you-for-downloading/?dl=tgz
权限管理
nexus目录描述
仓库类型描述
settings.xml的配置来说nexus仓库