概述:
Maven 是一个项目管理工具,主要用于项目构建,依赖管理,项目信息管理。
Maven 是一个项目管理工具,它包含了一个项目对象模型,一组标准集合,一个项目生命周期,一个依赖管理系统,和用来运行定义在生命周期阶段中插件目标的工具。
Maven 翻译为"专家"、"内行",是 Apache 下的一个纯 Java 开发的开源项目。
作用:
1.依赖管理
自动下载jar
maven仓库共享
2.项目构建
指的是项目从编译、测试、打包、安装,部署整个过程都交给maven进行管理,这个过程称为构建。
一键构建指的是整个构建过程,使用 maven 一个命令可以轻松完成整个工作。
安装:
下载后配置环境变量
http://maven.apache.org/download.cgi
MAVEN_HOME: maven安装目录
path: %MAVEN_HOME%\bin
目录结构:
bin:存放了 maven 的命令
boot:存放了一些 maven 本身的引导程序,如类加载器等
conf:存放了 maven 的一些配置文件,如 setting.xml 文件
lib:存放了 maven 本身运行所需的一些 jar 包
Maven仓库的分类:
1. 本地仓库
项目通过jar坐标,先从本地仓库找对应jar包,如果找不到会从远程仓库(互联网)去下载 jar包,保存在本地仓库(在程序员的电脑上),第二次不需要从远程仓库去下载。
配置:
修改 maven的安装目录/conf/settings.xml 文件的标签
<localRepository>本地仓库地址</localRepository>
2. 远程仓库
2.1 中央仓库
由专业团队(maven团队)统一维护。中央仓库的地址:http://repo1.maven.org/maven2/
2.2 私服
架设在公司局域网内,提供给内部的人员使用。
配置方式:
1.<repositories>增加仓库
直接在pom.xml配置
在settings.xml配置
2.<mirror>通过<mirrorOf>拦截指定仓库的请求到mirror,可以通过*,repo1,*,!repo1来选定规则。
2.3 第三方仓库
中央仓库只有一个国内使用非常慢,我们可以更换为:阿里云
修改 maven 根目录下的 conf 文件夹中的 setting.xml 文件,在 mirrors 节点上,添加内容如下:
<mirrors>
<mirror>
<id>ali-pub</id>
<mirrorOf>central</mirrorOf> // 匹配repositoryId,Maven 默认有一个 super pom 文件。id为central。不会被repository设置给覆盖。
<name>aliyun maven public</name>
<url>https://maven.aliyun.com/repository/public</url>
</mirror>
</mirrors>
settings.xml文件配置:
localRepository:
概述:
该值表示构建系统本地仓库的路径。
示例:
<localRepository>${user.home}/.m2/repository</localRepository>
interactiveMode:
概述:
表示maven是否需要和用户交互以获得输入。
示例:
<interactiveMode>true</interactiveMode>
usePluginRegistry:
概述:
maven是否需要使用~/.m2/plugin-registry.xml文件来管理插件版本。
示例:
<usePluginRegistry>false</usePluginRegistry>
offline:
概述:
表示maven是否需要在离线模式下运行。
示例:
<offline>false</offline>
pluginGroups:
servers:
概述:
配置服务端的一些设置。一些设置如安全证书不应该和pom.xml一起分发。这种类型的信息应该存在于构建服务器上的settings.xml文件中
mirrors:
概述:
镜像
proxies:
概述:
用来配置不同的代理。
profiles:
概述:
可以给项目pom.xml文件设置一些属性,不同环境的profiles可以配置不一样。
它的值会覆盖任何其它定义在pom.xml中带有相同id的profile
activeProfiles:
概述:
手动激活profiles的列表
POM文件配置:
properties标签:
概念:
变量存储
示例:
<properties>
<spring.version>5.1.5.RELEASE</spring.version>
<springmvc.version>5.1.5.RELEASE</springmvc.version>
<mybatis.version>3.5.1</mybatis.version>
</properties>
使用:
${mybatis.version}
repositories:
概述:
配置仓库。
示例:
<repositories>
<repository>
<id>joda</id>
<name>joda</name>
<url>https://www.ebi.ac.uk/intact/maven/nexus/content/repositories/public/</url>
</repository>
</repositories>
Maven 项目文件结构:
src/main/java - 存放项目.java文件;
src/main/resources - 存放项目资源文件;
src/test/java - 存放测试类.java文件;
src/test/resources - 存放测试资源文件;
target - 项目输出目录;
pom.xml - Maven核心文件(Project Object Model);需要哪个依赖,通过坐标形式引入。
Web项目:
src
main
webapp 页面资源
WEB_INF
web.xml web工程核心配置文件
index.jsp
css、js、img..
Maven生命周期和插件:
我们可以在 cmd 中通过一系列的 maven 命令,来对我们的工程进行清理、编译、测试、打包、安装、部署。
1)clean 删除target目录及内容。
2)compile 将src/main/java 下的文件编译为class文件输出到target目录下。
3)test 执行 src/test/java 下单元测试类,并编译为class文件。
4)package 对于java工程执行package打成jar包,对于web工程打成war包。(pom.xml配置)
5)install 执行install将mave工程打成jar包或war包,并发布到本地仓库。
6)deploy 将jar或war包部署(上传)到私服中。
生命周期:
maven 对项目构建过程分为“三套相互独立的”生命周期,这三套生命周期分别是:
1. Clean Lifecycle(清理生命周期)
在进行真正的构建之前进行一些清理工作。
命令:clean
2. Default Lifecycle(默认生命周期)
构建的核心部分,编译,测试,打包,部署等等。
命令: compile test package install deploy
3. Site Lifecycle(站点生命周期)
生成项目报告,站点,发布站点。
命令: site
* 在同一个生命周期中的命令,执行后面的命令,前面的命令自动执行
IDEA配置:
settings里面可以配置maven
runner配置-DarchetypeCatalog=internal -Dfile.encoding=GB2312
java工程转web工程需要JBJavaToWeb插件
新建项目:
mvn archetype:generate \
-DarchetypeGroupId=org.apache.flink \
-DarchetypeArtifactId=flink-quickstart-java \
-DarchetypeVersion=1.8.0
依赖范围:
依赖范围 对于编译classpath有效 对于测试classpath有效 对于运行时classpath有效 例子
compile(默认) Y Y Y mybatis
test - Y - junit
provided Y Y - servletapi(servlet api 被 tomcat 容器提供。)
runtime - Y Y JDBC驱动
依赖传递:
介绍:
在maven中,依赖是可以传递的,假设存在三个项目,分别是项目A,项目B以及项目C。假设C依赖B,B依赖A,那么我们可以根据maven项目依赖的特征不难推出项目C也依赖A。
依赖冲突:
现象:
不同依赖使用同一个依赖的不同版本
如何解决:
1.使用maven提供的依赖调解原则
第一声明者优先原则:
在 pom 文件中定义依赖,以先声明的依赖为准。其实就是根据坐标导入的顺序来确定最终使用哪个传递过来的依赖。(调整可能产生新的问题)
路径近者优先原则:
直接依赖大于依赖传递
2.排除依赖
可以使用exclusions标签将传递过来的依赖排除出去。
在某个dependency标签添加exclusions标签,排除子依赖.
3.锁定版本
采用直接锁定版本的方法确定依赖jar包的版本,版本锁定后则不考虑依赖的声明顺序或依赖的路径,以锁定的版本为准添加到工程中,此方法在企业开发中经常使用。
版本锁定的使用方式:
第一步:在dependencyManagement标签中锁定依赖的版本
第二步:在dependencies标签中声明需要导入的maven坐标,版本可以不带。
聚合工程:
分模块构建:
介绍:
在企业项目开发中,由于项目规模大,业务复杂,参与的人员比较多,一般会通过合理的模块拆分将一个大型的项目拆分为N多个小模块,分别进行开发。而且拆分出的模块可以非常容易的被其他模块复用
常见:
第一种:按照业务模块进行拆分,每个模块拆分成一个maven工程,例如将一个项目分为用户模块,订单模块,购物车模块等,每个模块对应就是一个maven工程
第二种:按照层进行拆分,例如持久层、业务层、表现层等,每个层对应就是一个maven工程
maven工程的继承:
介绍:
在maven工程之间也可以继承,子工程继承父工程后,就可以使用在父工程中引入的依赖。同一的版本锁定和依赖管理
继承的目的是为了消除重复代码。
分类:
父工程:
<packaging>pom</packaging>父工程的打包方式为pom
子工程:
<parent> //通过parent标签进行继承。
<groupId>
<artifactId>
<version>
</parent>
依赖建立原则:
当前工程需要哪个,就引入(直接,间接都存在),填写groupId和artifactId以及version
maven工程的聚合(不一定要继承关系)
在maven工程的pom.xml文件中可以使用标签将其他maven工程聚合到一起,聚合的目的是为了进行统一操作。
需要打包的时候,只需要在此工程中执行一次打包命令,其下被聚合的工程就都会被打包了。
<modules>
<module>ssm_domain</domain>
<module>ssm_domain</domain>
</modules>
mvn打包方式:
常用方式:
不加任何插件,直接使用mvn package打包;
使用maven-assembly-plugin插件;
使用maven-shade-plugin插件;
使用maven-jar-plugin和maven-dependency-plugin插件;
mvn package
概述:
不在POM中配置任何插件,直接使用mvn package进行项目打包,这对于没有使用外部依赖包的项目是可行的。但如果项目中使用了第三方JAR包,就会出现问题,因为mvn package打的JAR包中是不含有依赖包,会导致作业运行时出现找不到第三方依赖的异常。这种方式局限性比较大,因为实际的项目往往很复杂,通常都会依赖第三方JAR。
缺点:
基本所有的框架都支持在提交作业时使用--jars指定第三方依赖包,但是这种方式的问题同样很明显,就是你必须保持生产环境与开发环境中的所有JAR包版本一致,这是有维护成本的。
解决:
最简单的是采用All In One的打包方式,把所有依赖都打包到一个JAR文件中,此时对环境的依赖性最小。要实现这个目的,可以使用Maven提供的maven-assembly-plugin或maven-shade-plugin插件。
maven-assembly-plugin插件
概述:
Assembly插件支持将项目的所有依赖、文件都打包到同一个输出文件中。
打包后会同时生成两个JAR包,其中后缀为jar-with-dependencies是含有第三方依赖的JAR包,后缀是由assembly.xml中<id>标签指定的,可以自定义修改。
maven-shade-plugin插件
概述:
maven-shade-plugin比maven-assembly-plugin功能更为强大,比如你的工程依赖很多的JAR包,而被依赖的JAR又会依赖其他的JAR包,这样,当工程中依赖到不同的版本的 JAR时,并且JAR中具有相同名称的资源文件时,shade插件会尝试将所有资源文件打包在一起时,而不是和assembly一样执行覆盖操作。
通常使用maven-shade-plugin就能够完成大多数的打包需求,其配置简单且适用性最广,因此建议优先使用此方式。
打包后会生成两个JAR包,提交到服务器集群时使用非original开头的JAR。
包依赖冲突:
relocation配置,将包重命名。
使用:
可以配置<artifactSet><includes>来声明哪些依赖需要打包。
<include>**</include>表示全部依赖需要引入。
其他打包需求:
1.使用非Maven仓库中的Jar
果你想把某些没有被Maven管理JAR包打入到最终的JAR中,比如你在resources/lib下引入的其他非Maven仓库中的JAR,此时可以使用maven-jar-plugin和maven-dependency-plugin插件将其打入最终的JAR中。
2. 排除集群中已经存在的Jar
排除JAR包的方式主要有两种:
对需要排除的依赖添加<scope>provided</scope>标签,此时该JAR包会被排除,但是不建议使用这种方式,因为此时你在本地运行也无法使用该JAR包;
建议直接在maven-assembly-plugin或maven-shade-plugin的配置文件中使用<exclude>进行排除。
3.打包Scala文件
默认情况下Maven是不会把scala文件打入最终的JAR中,需要额外添加maven-scala-plugin插件
常用的goal:
compile 编译scala code
testCompile 编译test code
如果报错classnotfound:org_scala_tools_maven_executions.MainWithArgsInFile:
注意这个plugin下载的来源。之前用了nexus,改为ali后正常编译。
框架简介:
持久层框架:专注于解决数据持久化的框架。常用的有mybatis、hibernate(全自动)、spring jdbc等等。
表现层框架:专注于解决与用户交互的框架。常见的有struts2、spring mvc等等。
全栈框架: 能在各层都给出解决方案的框架。比较著名的就是spring。
最常用的组合为准来学习Spring + Spring MVC + mybatis(SSM)
maven依赖最小化:
方法1:
通过include来指定(maven插件第一级的即可,control+o搜索类名),需要一个个判断哪些依赖是必须的。
缺点:
慢,一个个试
有些依赖比较难找,control+o不一定能搜到,需要结合maven repository来搜索
方法2:
<configuration>
<minimizeJar>true</minimizeJar>
</configuration>
减小了一定体积,但还是比较大。
方法3:
先正常打包
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.coolpad.bigdata.bi.mau.GenShare2Mysql</mainClass>
<layout>ZIP</layout>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
然后修改配置
<includes>
<include>
<groupId>nothing</groupId>
<artifactId>nothing</artifactId>
</include>
</includes>
部署的时候只要指定java -Dloader.path="lib/" -jar xxx.jar即可。(loader.path不能和-cp共用)
注意事项:
1.original-前缀的不包含依赖,MANIFEST.MF不包含main-class和start-class。
2.-cp是-classpath,用法:
java -cp path <mainclass> [args...]
只能运行original-前缀的包
3.-jar只能运行打包时指定的主类,只能运行不带original前缀的。
maven-shade-plugin插件打包没有指定主类,只能-cp运行,jar会报错no main manifest attribute, in bi-spark-1.0-SNAPSHOT.jar
文档:
https://docs.spring.io/spring-boot/docs/current/maven-plugin/reference/htmlsingle/
缺点:
每次新增依赖都需要更新lib目录
方法4:
全部include,手动exclude
<artifactSet>
<excludes>
<exclude>org.json4s:*</exclude>
</excludes>
</artifactSet>