Maven (一)--- 入门和依赖
部分图片来自参考资料
问题 :
- maven 生命周期是怎么样的
- mvn clean install 与 mvn clean deploy 的区别是什么
概述
Maven 是一种构建项目的工具,能够帮我们自动化构建过程,从清理,测试到生成报告,再到打包和部署,不仅如此它还是一个依赖管理工具和项目信息管理工具,它提供了中央仓库,能帮我们自动下载构件。
Maven 安装注意事项
Maven 安装的教程我就不再重复讲解,主要就是先安装JDK,然后配置环境变量,正常安装即刻。Maven 用户可以选择配置 安装路径下/conf/settings.xml 或是 ~/.m2/settings.xml ,前者是全局范围,后者是用户返回,只有当前用户才会受影响。例如,在我的电脑中,前后者的路径分别为 :
E:\software\maven\apache-maven-3.5.4-bin\apache-maven-3.5.4\conf
C:\Users\Benjious\.m2\repository
示例 maven 文件
<?xml version="1.0" encoding="UTF-8"?>
<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.general</groupId>
<artifactId>general-msg</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>general-msg-api</module>
<module>general-msg-bit</module>
</modules> <parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.2.RELEASE</version>
</parent> <properties>
<java.version>1.8</java.version>
<mybatis.version>3.3.1</mybatis.version>
<mybatis.spring.version>1.2.4</mybatis.spring.version>
<mysql.connector.version>5.1.40</mysql.connector.version>
<fasterxml.jackson.version>2.8.4</fasterxml.jackson.version>
<spring.boot.version>1.4.2.RELEASE</spring.boot.version>
<spring.session.version>1.2.2.RELEASE</spring.session.version>
<spring.mongodb.version>2.0.3.RELEASE</spring.mongodb.version>
</properties> <dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring.boot.version}</version>
<!--<exclusions>-->
<!--<exclusion>-->
<!--<groupId>org.springframework.boot</groupId>-->
<!--<artifactId>spring-boot-starter-tomcat</artifactId>-->
<!--</exclusion>-->
<!--</exclusions>-->
</dependency> <!-- dubbo start -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.5.3</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
</exclusion>
</exclusions>
</dependency> <dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.6</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
</exclusions>
</dependency> <dependency>
<groupId>com.github.sgroschupf</groupId>
<artifactId>zkclient</artifactId>
<version>0.1</version>
</dependency> <dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.4</version>
</dependency> <!--mybatis相关依赖开始-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.connector.version}</version>
</dependency> <dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis.version}</version>
</dependency> <dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>${mybatis.spring.version}</version>
</dependency>
<!--mybatis先关依赖结束--> <!--mybatis逆向工程插件-->
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.2</version>
<scope>compile</scope>
<optional>true</optional>
</dependency> </dependencies>
</dependencyManagement> <distributionManagement>
<!-- 两个ID必须与 setting.xml中的<service><id>nexus-releases</id></service>保持一致 -->
<repository>
<id>nexus-releases</id>
<name>Nexus Release Repository</name>
<url>http://192.168.10.241:8081/repository/maven-releases/</url>
</repository>
<snapshotRepository>
<id>nexus-snapshots</id>
<name>Nexus Snapshot Repository</name>
<url>http://192.168.10.241:8081/repository/maven-snapshots/</url>
</snapshotRepository>
</distributionManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<!-- 要将源码放上去,需要加入这个插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
<configuration>
<attach>true</attach>
</configuration>
</plugin>
</plugins>
</build>
</project>
初步实践
我们先使用maven构建一个简单的项目,新建文件和文件夹如下图 ,test 文件夹和main 文件夹同级。
以下是 Main.java 文件和 pom.xml 文件。
package com.vb.bengmall;
public class Main{
public String sayHello(){
return "Hello Maven";
} public static void main(String[] args){
System.out.print(new Main().sayHello());
}
}
<?xml version="1.0" encoding="UTF-8"?>
<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.vb.bengmall</groupId>
<artifactId>bengmall</artifactId>
<version>1.0-SNAPSHOT</version>
<name>Maven Hello World Project</name>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies> </project>
还有test测试文件 :
import com.vb.bengmall.Main; import static org.junit.Assert.assertEquals; import org.junit.Test; public class MainTest {
@Test
public void testSayHello() {
Main m = new Main();
String result = m.sayHello();
assertEquals("Hello Maven",result);
}
}
然后在src 目录下依次执行 : mvn clean compile 和 mvn clean test ,就会发现 src 生成了一个 target目录,里面就是我们编译和测试生成的文件,执行过程如图 :
接下来是 mvn clean package ,我们看到执行日志,maven 执行的是插件的 clean ,resources,compiles,testResources,testCompile,test ,jar 几个步骤,我们后面再详细学习这几个过程,现在打开target 文件夹下你就会发现里面有个jar,这正是我们打包出来的jar 文件,好了,打包成功后,我们需要将项目放在maven 仓库中,方便以后其他项目引用,这里就要执行 mvn clean install
打开以下路径(见下图),你就发现自己项目生成的jar放在了maven 仓库中了。
要是每次构建项目都要自己建文件夹,配置pom 难免有些繁琐麻烦,maven 也提供一些骨架供大家下载使用,执行mvn archetype:generate 命令,maven就会弹出来让你选择哪种框架,选择后就会让你填写 groupid等等基本信息,然后生成一个开发骨架。
通过上面的小实例,我们从compile ,test ,package 到最后的install 我们相当于把构建项目的过程走了一遍,当然实际中可能需要更多的步骤,以上步骤是让读者对maven 有个初步的印象。
依赖
maven 坐标
maven 通过定义groupId, artifactId, version , packaging , classifier 。在maven的世界里,任何一个依赖,插件或者项目构建的输出,都可以称为构件。 坐标详解:
- groupId : 定义当前 Maven 项目隶属的实际项目。
- artifactId : 该元素定义实际项目中的一个 Maven 项目(模块),推荐的做法是使用实际项目名称作为 artifactId 的前缀。
- version : 版本,需要注意快照版本(SNAPSHOT)的学习和理解
- packaging : 打包方式
- classifier : 该元素用来帮助定义构建输出一些附属构件。
依赖配置
<project>
<dependencies>
<dependency>
<groupId>...</groupId>
<artifactId>...</artifactId>
<version>...</version>
<type>...</type>
<scope>...</scope>
<optional>...</optional>
<exclusions>
<exclusion>...</exclusion>
</exclusions>
</dependency> <dependency>
...
</dependency> <dependency>
...
</dependency>
</dependencies> </project>
groupId , artifaceId , version 三者可以定义一个依赖的坐标,另外的配置 :
- type : 依赖的类型,大部分不必声明。
- scope : 依赖范围,下文详解
- optional : 少用
- exclusions : 用来排除传递性依赖
依赖的范围有
- compile : 没指定,默认是这个范围
- test : 测试范围,在编译主代码或者运行项目的时候无法使用该类依赖
- provided : 在编译和测试有效,但在运行中无效,典型的就是 servlet-api , 编译和测试项目的时候是需要该依赖的,但在运行时由于容器有提供这不需要。
- runtime : 测试和运行有效,但在编译主代码时无效。典型的就是 JDBC 驱动实现了,项目编译只要 JDK 提供的JDBC 接口,只有在执行测试或者运行项目的时候才需要实现上述接口的具体JDBC 驱动。
- system : 系统依赖范围,和provided 依赖范围完全一致,由于该类依赖不是通过maven 仓库解析的,而且往往与本机系统绑定,可能造成构建的不可移植,应谨慎使用。
- import : 后面介绍
传递性依赖和传递性的依赖范围
假如我们有一个叫 account-email 的项目,依赖如下 :
那么 account-email 和 commons-logging 之间就存在一个传递性依赖。具体的依赖类型如下图 :
依赖调解
对于依赖有两个重要的原则 :
- 路径最近者优先
- 第一声明者优先
最佳实践
排除依赖,例如由于传递性依赖中引入了不稳定的SNAPSHOT版本依赖,现在想把它移除掉,
pom 文件示例如下 :
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.juvenxu.mvnbook</groupId>
<artifactId>project-b</artifactId>
<version>${spring.boot.version}</version>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
....
<dependencyManagement>
查看当前 maven 中已经解析的依赖 :
mvn dependency:list
仓库
maven 仓库是基于简单文件系统存储的,例如在我们的logback 这个构件存在在我们本地仓库的位置。如下图 :
不同版本的logback 以文件的形式在本地存储。
仓库分类
可以知道大体分为远程仓库和本地仓库两类。
本地仓库
本地仓库的地址默认是 ~/.m2/resposity ,我们可以通过 setting.xml 文件来进行修改 。
<settings>
<localRepository>D:\java\repository\</localRepository>
</settings>
私服
可以说私服就像是浏览器一样,帮助客户请求远程服务器的资源,用户也可以上传和下载构件。
远程仓库
mvn clean deploy 就是将项目部署到远程仓库中去,在本篇的示例代码中,部署到远程仓库中的配置如下 :
<distributionManagement>
<!-- 两个ID必须与 setting.xml中的<service><id>nexus-releases</id></service>保持一致 -->
<repository>
<id>nexus-releases</id>
<name>Nexus Release Repository</name>
<url>http://192.168.10.241:8081/repository/maven-releases/</url>
</repository>
<snapshotRepository>
<id>nexus-snapshots</id>
<name>Nexus Snapshot Repository</name>
<url>http://192.168.10.241:8081/repository/maven-snapshots/</url>
</snapshotRepository>
</distributionManagement>
生命周期
可以说maven 构建项目的过程分为 : 编译,测试,打包,部署。而maven 本身有三套独立的生命周期,分别为 : clean(清理项目),default(构建项目),site(建立项目站点) 。
插件
插件的执行实际就是声明周期的过程,插件与生命周期有一个绑定的关系,例如 :
聚合与继承
聚合
聚合的作用主要是使编译的时候一起编译。
<modules>
<module>general-msg-api</module>
<module>general-msg-bit</module>
</modules>
继承
继承的作用主要是让子类省去一些重复的工作。
<parent>
<artifactId>general-msg</artifactId>
<groupId>com.general</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
可继承的属性有
依赖管理
我们从上面也可以知道 dependencies 和 dependencyManagement 都是可从父类中继承的,例如在父类的 dependencyManagement 中定义的
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring.boot.version}</version>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
<version>${spring.boot.version}</version>
</dependency>
在子类中可以直接省略了版本号,这样也方便项目管理,使得多个子类和父类都使用同一个版本,不会造成混乱。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
maven 提供的 dependencyManagement 元素既能让子模块继承到福模块的依赖配置,又能保证子模块依赖使用的灵活性。在 dependencyManagement 元素下的依赖声明不会不会引入实际的依赖,不过它能够约束 dependencies 下的依赖使用。
问题
- mvn clean install 与 mvn clean deploy 的区别是什么
总结
本文主要介绍maven 的工作过程,需要重点把握的是maven的生命周期和继承聚合以及依赖的相关概念,在学习中最好结合文章开头的实例进行比对学习。
参考资料
- maven 实战
- 工匠人生公众号 --- 【朝花夕拾】Maven拾遗 一文
Maven (一)--- 入门和依赖的更多相关文章
- Maven快速入门(五)Maven的依赖管理
前面我们讲了maven项目中的最重要的文件:pom.xml 配置文件相关内容.介绍了pom 是如何定义项目,如何添加依赖的jar 包的等. 我们知道,在Maven的生命周期中,存在编译.测试.运行等过 ...
- Maven——快速入门手册(学习记录)
前言: 前段时间进行了一点maven的入门学习,在这里做个记录,希望能帮到一些正在学习的朋友们.maven版本为3.3.9.希望大家觉得好的点个赞,觉得不好的多提提意见和建议做个交流.这里也贴出我学习 ...
- (4)Maven快速入门_4在Spring+SpringMVC+MyBatis+Oracle+Maven框架整合运行在Tomcat8中
利用Maven 创建Spring+SpringMVC+MyBatis+Oracle 项目 分了三个项目 Dao (jar) Service (jar) Controller (web) ...
- Maven 学习(一)-Maven 使用入门
http://www.cnblogs.com/xdp-gacl/p/3498271.html http://www.cnblogs.com/xdp-gacl/p/4240930.html 一.Mave ...
- Maven系列学习(二)Maven使用入门
Maven使用入门 通过上一节的学习,我们已经了解和配置好了Maven,接下来需要编写代码了 1.POM(Project Object Model,项目对象模型) 和Make的Makefile类似,M ...
- Maven快速入门(一)Maven介绍及环境搭建
做开发的程序员都知道,在系统开发需要各自各样的框架.工具.其中有一种工具不管你是初级程序员还是高级程序员都必须熟练掌握的,那就是项目管理工具(maven.ant.gradle).接下来就总结Maven ...
- Maven快速入门(二)手动创建maven项目hellomaven
之前讲过Maven介绍及环境搭建,介绍了maven的作用和如何搭建maven环境.接下来就以一个helloworld的例子来说一说如何创建maven项目以及maven项目的项目结构,最后讲maven如 ...
- Maven快速入门(三)Maven的坐标和仓库
之前通过一个helloworld的例子来说一说如何创建maven项目以及maven项目的项目结构,然后讲maven如何编译运行项目.接下来介绍maven中几个比较重要的概念:坐标和仓库.Maven快速 ...
- Spring4.3入门 Spring 依赖关系
Spring4.3入门 Spring 依赖关系 spring的jar包只有20个左右,每个都有相应的功能,一个jar还可能依赖了若干其他jar ,所以,搞清楚它们之间的关系,配置maven依赖就可以简 ...
- maven 打包含有第三方依赖的 jar 包
maven 打包含有第三方依赖的 jar 包:mvn assembly:assembly
随机推荐
- Spring核心知识
目录 Spring 概述 依赖注入 Spring beans Spring注解 Spring数据访问 Spring面向切面编程(AOP) Spring MVC Spring 概述 1. 什么是spri ...
- 番外:克隆本地PDB中其他参数和子句的说明
基于版本:19c (12.2.0.3) AskScuti 创建方法:克隆本地PDB(从本地其他PDB创建新的PDB) 对应路径:Creating a PDB --> Cloning --> ...
- php核心技术与最佳实践 --- 错误与异常
<?php /*php error*/ /* * 异常和错误的概念不一样 * 在PHP里,遇到任何自身错误都会触发一个错误,而不是抛出异常(对于一些情况,会同时抛出异常和错误) * 异常处理机制 ...
- go 语言实现栈原理
package main import "fmt" type StackNode struct { Data interface{} //数据 Next *StackNode // ...
- setInterval 和 setTimeout 定时器
前端定时器 setInterval 和 setTimeout setInterval 循环执行 循环执行就是设置一个时间间隔,每过一段时间都会执行一次这个方法,直到这个定时器被销毁掉. 用法是setI ...
- 【Html】Html基本标记
<!doctype html> <html> <head> <!--mata 元信息标记--> <meta charset="utf-8 ...
- DFT 问答 III
1.Boundary scan Boundary Scan就是我们俗称的边界扫描.Boundary Scan是上世纪90年代由 Joint Test Action Group(JTAG)提出的,它的初 ...
- google插件跨域含用户请求WebApi解决的方案
问题描述: google插件跨域请求WebApi相关解决方案 1.ajax解决含登录用户信息 $.ajax({ url: url, type: "POST", timeout: 6 ...
- KALI修改密码
许久不用的Kali,某天打开竟忘了密码! 网上的方法颇为简单,遂准备亲自试一下. #光标移动到第二行的“恢复模式”,按E进入[编辑模式] #进入编辑模式,鼠标是不可操作的,用方向键往下面翻 ...
- CDH的坑之Deploy Client Configuration Failed
Deploy Client Configuration Failed 1.问题描述 当使用CDH增添spark服务的时候,出现了以下错误: Faile to deploy client configu ...