maven和gradle区别 | |
---|---|
https://www.cnblogs.com/huang0925/p/5209563.html
Gradle
开源自动化构建工具,基于特定领域语言Groove
Gradle安装请参考其他博客.
Groove基于java虚拟机的敏捷动态语言,面向对象的编程语言,也可以做脚本语言
// buildscript 代码块中脚本优先执行
buildscript {
// ext 用于定义动态属性
ext {
springBootVersion = '1.5.2.RELEASE'
}
// 自定义 Thymeleaf 和 Thymeleaf Layout Dialect 的版本
ext['thymeleaf.version'] = '3.0.3.RELEASE'
ext['thymeleaf-layout-dialect.version'] = '2.2.0'
// 自定义 Hibernate 的版本
ext['hibernate.version'] = '5.2.8.Final'
// 使用了 Maven 的中央仓库(你也可以指定其他仓库)
repositories {
//mavenCentral()
maven {
url 'http://maven.aliyun.com/nexus/content/groups/public/'
}
}
// 依赖关系
dependencies {
// classpath 声明说明了在执行其余的脚本时,ClassLoader 可以使用这些依赖项
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
// 使用插件
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
// 指定了生成的打包的版本号
version = '1.0.0'
// 指定编译 .java 文件的 JDK 版本
sourceCompatibility = 1.8
// 默认使用了 Maven 的中央仓库。这里改用自定义的镜像库
repositories {
//mavenCentral()
maven {
url 'http://maven.aliyun.com/nexus/content/groups/public/'
}
}
// 依赖关系
dependencies {
// 该依赖对于编译发行是必须的
compile('org.springframework.boot:spring-boot-starter-web')
//aop
compile('org.springframework.boot:spring-boot-starter-aop')
// 添加 Thymeleaf 的依赖
compile('org.springframework.boot:spring-boot-starter-thymeleaf')
// 添加 Spring Data JPA 的依赖
compile('org.springframework.boot:spring-boot-starter-data-jpa')
// 添加 MySQL连接驱动 的依赖
compile('mysql:mysql-connector-java:6.0.5')
// 添加 H2 的依赖
runtime('com.h2database:h2:1.4.193')
// 添加 Spring Data Elasticsearch 的依赖
compile('org.springframework.boot:spring-boot-starter-data-elasticsearch')
//jna依赖,否则项目启动时,会报classNotFound: native method disable的错误
compile("com.sun.jna:jna:3.0.9")
// 添加 Spring Security 依赖
compile('org.springframework.boot:spring-boot-starter-security')
// 添加 Thymeleaf Spring Security 依赖
compile('org.thymeleaf.extras:thymeleaf-extras-springsecurity4:3.0.2.RELEASE')
// 添加 Apache Commons Lang 依赖
compile('org.apache.commons:commons-lang3:3.5')
// 该依赖对于编译测试是必须的,默认包含编译产品依赖和编译时依
testCompile('org.springframework.boot:spring-boot-starter-test')
//添加markdown parser
compile('es.nitaur.markdown:txtmark:0.16')
//阿里 easyExcel
compile("com.alibaba:easyexcel:1.0.4")
}
构建
编译为jar后
maven 依赖管理 | ||
---|---|---|
Maven
下载
Maven是Apache软件基金会唯一维护的一款自动化构建工具,专注于服务Java平台的项目构建和依赖管理。
https://archive.apache.org/dist/maven/maven-3/
由java编写,需要jre运行环境JAVA_HOME
根据 组织,项目,版本 从 仓库 找到jar
查找顺序 本地>私服>远程仓库
maven 常用命令
生成idea项目:mvn idea:idea
编译 ,测试 , 运行 , 打包, 安装 都交给maven构建
mvn clean
清除target目录下文件
mvn compile
编译出classes
mvn test
编译了源代码,测试代码,运行测试代码
mvn package
编译源代码,测试代码,运行测试代码,打包
mvn -Dtest package
组合使用goal命令,如只打包不测试
package -Dmaven.test.skip=true -f pom.xml
mvn install
编译源代码,测试代码,运行测试代码,打包,放到本地仓库
mvn tomcat:run
版本 mvn versions:set -DnewVersion=1.3.1 -DgenerateBackupPoms=false
一、依赖
dependencyManagement 父pom的依赖管理
统一管理项目的版本号,确保应用的各个项目的依赖和版本一致
1. maven依赖范围
默认是compile,可选配置有test、provided、runtime、system、import
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.7</version>
<scope>test</scope>
</dependency>
2. maven传递性依赖
在项目往往需要引入多个依赖, 而引入的依赖又会引入其他的依赖。
例如: 项目中引入了spring-core依赖, 而spring-core又依赖commons-logging。因为项目直接引入了spring-core依赖,则spring-core为项目的第一直接依赖, 而因为spring-core引入了commons-logging依赖, 则commons-logging为项目的一个传递性依赖。
有了Maven的传递性依赖机制,不用担心引入多余的依赖。 Maven会解析各个直接依赖的POM, 将那些必要的间接依赖,以传递性依赖的形式引入到当前的项目中。
3. maven依赖调解
例如, 项目A有这样的依赖关系:A->B->C->X(1.0), A->D->X(2.0), X是A的传递性依赖,但是两条依赖路径上有两个版本的X, 那么哪个X会被Maven解析使用呢?两个版本都解析显然是不对的,因为那会造成依赖重复,因此必须选择一个。Maven依赖调解的第一原则是:最短路径优先。该例中X(1.0)的路径长度为3,而X(2.0)的路径长度为2,因此X(2.0)会被解析使用。
依赖调解第一原则不能解决所有问题,比如这样的依赖关系: A->B->Y(1.0), A->C->Y(2.0), Y(1.0) 和 Y(2.0)的依赖路径长度是一样的,都为2,。 那么到底谁会被解析使用呢?在Maven2.0.8及之前的版本中,这是不确定的, 但是从Maven2.0.9开始,为了尽可能避免构建的不确定性,Maven定义了依赖调解的第二原则:两条路都是一样长,两个工程**谁在前面就是用哪个版本。但不一定生效 , 往往是这种路径一致造成jar冲突**。在依赖路径长度相同的情况下,在POM中依赖声明的顺序决定了谁会被解析使用,顺序最靠前的那个依赖优胜。该例中,如果B的依赖声明在C之前,那么Y(1.0)就会被解析使用。
4. maven可选依赖
假设有这样一个依赖关系,项目A依赖与项目B,项目B依赖于项目X和Y, B对于X和Y的依赖都是可选依赖: A->B, B->X(可选),
B->Y(可选)。 根据传递性依赖的定义,如果所有这三个依赖的范围都是compile,那么X, Y就是A的compile范围传递性依赖。然而,由于这里X,Y是可选依赖,依赖将不会得以传递。换句话说,X,Y将不会对A有任何影响。
为什么要使用可选依赖这一特性呢?可能项目B实现了两个特性,其中的特性一依赖于X,特性而依赖于Y,而且两个特性时互斥的,用户不能同时使用两个特性。比如B是一个持久层隔离工具包,它支持多种数据库,报错MySQL, PostgreSQL等,在构建这个工具包的时候, 需要这两种数据库的驱动程序,但在使用这个工具包的时候,只会依赖一种数据库。项目B的依赖声明如下:
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.10</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>8.4-701.jgbc3</version>
<optional>true</optional>
</dependency>
</dependencies>
上述代码片段中, 使用元素表示mysql-connector-java和postgresql这两个依赖为可选依赖,它们只会对当前项目B产生影响,当其他项目依赖于B的时候,这两个依赖不会被传递。因此,当项目A依赖于项目B的时候,如果其实际使用基于MySQL数据,那么项目A中就需要显示的声明mysql-connetor-java这一依赖,如下:
<dependencies>
<dependency>
<groupId>org.rogueq.mvnbook</groupId>
<artifactId>project-b</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.10</version>
</dependency>
</dependencies>
5. maven排除依赖
<exclusions>
6. maven归类依赖
<properties>
二、仓库
1. 仓库种类
Maven 仓库能帮助我们管理构件(主要是JAR),它就是放置所有JAR文件(WAR,ZIP,POM等等)的地方。
Maven 仓库有三种类型:
- 本地(local) 它是在第一次执行 maven 命令的时候才被创建
- 中央(central) 由 Maven 社区提供的仓库,其中包含了大量常用的库。
- 远程(remote) 开发人员自己定制仓库
- 私服Necus
Maven 仓库默认在国外, 国内使用难免很慢,我们可以更换为阿里云的仓库。
第一步:修改 maven 根目录下的 conf 文件夹中的 setting.xml 文件,在 mirrors 节点上,添加内容如下:
<mirrors>
<mirror>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
</mirrors>
2. 搜索顺序
Maven 依赖搜索顺序
当我们执行 Maven 构建命令时,Maven 开始按照以下顺序查找依赖的库:
步骤 1 - 在本地仓库中搜索,如果找不到,执行步骤 2,如果找到了则执行其他操作。
步骤 2 - 在中央仓库中搜索,如果找不到,并且有一个或多个远程仓库已经设置,则执行步骤 4,如果找到了则下载到本地仓库中以备将来引用。
步骤 3 - 如果远程仓库没有被设置,Maven 将简单的停滞处理并抛出错误(无法找到依赖的文件)。
步骤 4 - 在一个或多个远程仓库中搜索依赖的文件,如果找到则下载到本地仓库以备将来引用,否则 Maven 将停止处理并抛出错误(无法找到依赖的文件)。
三、生命周期
四、面试题
1. “Mvn Clean Package”???
在这个命令中我们调用了maven的clean周期的clean阶段绑定的插件任务,以及default周期的package阶段绑定的插件任务
默认执行的任务有(maven的术语叫goal, 也有人翻译成目标,我这里用任务啦):
maven-clean-plugin:clean->
maven-resources-plugin:resources->
maven-compile-plugin:compile->
mavne-resources-plugin:testResources->
maven-compile-plugin:testCompile->
maven-jar-plugin:jar
2. Maven 依赖的解析机制是怎么样的?
解析发布(RELEASE)版本:如果本地有,直接使用本地的,没有就向远程仓库请求。
解析快照(SNAPSHOT)版本:合并本地和远程仓库的元数据文件 groupId/artifactId/version/maven-metadata.xml ,这个文件存的版本都是带时间戳的,将最新的一个改名为不带时间戳的格式供本次编译使用。
解析版本为 LATEST 过于复杂,且解析的结果不稳定,不推荐在项目中使用,感兴趣的同学自己去研究,简而言之就是合并groupId/artifactId/maven-metadata.xml 找到对应的最新版本和包含快照的最新版本。
? LASTEST、RELEASE、SNAPSHOT 的区别?
LASTEST :是指某个特定构件最新的发布版或者快照版(SNAPSHOT),最近被部署到某个特定仓库的构件。
RELEASE :是指仓库中最后的一个非快照版本。
SNAPSHOT :泛指。如果不 SNAPSHOT ,如果名字不变,本地有了不会从远程拉。如果每次更新都改名字,其他用的人也都改名字,太蛋疼了。
参考文章
https://blog.csdn.net/a303549861/article/details/93752178
https://blog.csdn.net/xzp_forever/article/details/87992971