[JAVA]-Maven框架
[JAVA]-Maven框架
[TOC]
1.Maven基础
<1>基础概念
🔖Maven基础概念
❓什么是Maven?
Maven是跨平台的项目管理工具,主要服务于基于Java平台的项目构建、依赖管理和项目信息管理
其本质是一个项目管理工具,将项目开发和管理过程抽象成一个项目对象模型(POM)
❓项目构建过程?
清理、编译、测试、报告、打包、部署
什么是理想的项目构建?
高度自动化,跨平台,可重用的组件,标准化的
什么是依赖?为什么要进行依赖管理?
自动下载,统一依赖管理
有哪些项目信息?
项目名称描述等,开发人员信息,开发者信息等
❓使用Maven前后对比
- 没有使用Maven之前
# 使用eclipse开发的步骤
清理(clean)
编译(java文件转换为class文件)
测试
报告(文档)
打包(生成jar包或者war包)
部署(部署到tomcat)
复制(SpringMVC+MyBatis的jar包)
- 使用Maven之后
# 使用eclipse开发的步骤,可以使用Maven的一步构建(只需要一个命令即可)
清理(clean)
编译(java文件转换为class文件)
测试
报告(文档)
打包(生成jar包或者war包)
部署(部署到tomcat)
通过一个配置(pom.xml)自动从互联网导入jar包
❓Maven依赖管理
Maven的依赖管理涉及资源的存放,主要理解三个概念:本地仓库、私服、中央仓库
本地仓库是存储在本地的一种资源仓库,如果本地仓库中没有相关资源,可以去私服(远程的资源仓库)上获取,如果私服上也没有相关资源,则可去中央仓库(远程的资源仓库)去获取
❓Maven作用
1)项目构建:提供标准的,跨平台的自动化构建项目的方式
2)依赖管理:方便快捷的管理项目依赖的资源(jar包),避免资源间的版本冲突等问题
3)统一开发结构:提供标准的,统一的项目开发结构
# 标准maven工程目录说明
src/main/java:项目java源码
src/main/resources:项目的相关配置文件(例如ssm先关配置、自定义配置文件等)
src/main/webapp:web资源(比如html,css,js等)
src/test/java:项目测试代码
src/test/resources:测试相关配置文件
src/pom.xml:项目pom文件(maven核心配置文件)
🔖Maven的优势
为什么使用Maven?
提升开发效率,解决项目开发、运维过程中的jar统一问题、减少项目维护成本
- IDEA?Eclipse?
基于开发工具的工程构建涉及手工操作较多,编译、测试、部署等工作都是独立的,很难一步完成。且每个开发者的开发环境配置都各不相同,很容易出现本地代码切换环境编译出错等问题,造成开发、维护项目效率低下
- Ant?
Ant没有一个约定的目录结构,必须明确让ant做什么,什么时候做,然后编译,打包
没有生命周期(需定义目标及其实现的任务序列)、没有集成依赖管理
- Maven?
有约定的项目目录结构,通过一个pom.xml文件约定规则,由Maven帮助处理工程管理相关的内容
拥有完整的生命周期,可以借助指令自动执行编译,测试,打包等构建过程,拥有依赖管理,仓库管理概念
⚡Maven的配置的安装
1>Windows下安装Maven
确认jdk是否已安装?
下载并安装Maven
a.下载Maven
b.Maven的目录结构
解压Maven-bin目录到指定文件夹(eg:E:\soft\maven\apache-maven-3.5.4)
c.配置环境变量
根据指定的maven的安装(解压)目录完成环境变量的配置
MAVEN_HOME =E:\soft\maven\apache-maven-3.5.4
Path= E:\soft\maven\apache-maven-3.5.4\bin
d.校验是否安装成功
此时验证需要配置JAVA_HOME ,在cmd窗口输入指令mvn -version
显示结果
2>Maven在eclipse中的配置
a.指定eclipse使用自定义的maven版本信息
Windows--->preference--->maven,根据下述提示完成maven配置
添加完成,选中当前的版本信息
b.指定用户的配置setting.xml
把E:\soft\maven\apache-maven-3.5.4\conf文件放置到C:\Users\yhtx-22.m2,如果此时还没有生成.m2文件目录则新建maven工程进行测试会自动生成相应的仓库目录
Window-->preference-->User Settings-->指定setting.xml的实际目录(默认在用户目录下的.m2/settings.xml)
完成上述配置,下述通过创建web项目进行相关测试
<2>Maven入门程序
maven项目的构建可以手动构建(需满足maven规范),也可借助开发工具提供的工程骨架进行构建
项目1:Hello
1>新建Maven项目
a.新建Maven项目
b.选择Maven骨架
c.查看建立完成的目录结构和指定库文件的变化
第一次加载Maven项目需要等待一段时间,等待相关内容加载完成再进行操作(如果长时间无反应,右键工程properties选择maven-->update project更新maven工程,等待完成即可)
Maven的目录结构每个目录都有自己的功能,也就是遵循Maven约定
遵从Maven约定
src/main/java —— 存放项目的.java文件
src/main/resources —— 存放项目资源文件,如spring, hibernate配置文件
src/test/java —— 存放所有测试.java文件,如JUnit测试类
src/test/resources —— 测试资源文件
target —— 项目输出位置
pom.xml —— maven依赖项配置(jar包配置)
2>配置pom.xml
修改jre为自定义的jdk版本,通过配置pom.xml可以实现jar包的导入、移除,可以更换Junit的jar包查看变化
通过在maven仓库官网查找相关jar包,直接复制相关代码进行配置即可
此处替换原有的junit-3.8.1.jar进行测试,查找最新的junit相关jar包进行替换
- 修改前
- 修改后
3>编码测试
Hello.java:
public class Hello {
public void sayHello(String name) {
System.out.println("Hello,"+name+"!");
}
}
HelloTest.java:
import static org.junit.Assert.assertEquals;
import org.junit.Test;
public class HelloTest {
@Test
public void testHello() {
Hello hello = new Hello();
String res = hello.sayHello("张三");
assertEquals("Hello,张三!", res);
}
}
程序执行测试:右键选择要测试的方法名,点击run as --> junit test进行测试
4>执行程序
选中pom.xml 右键 --> run as --> maven build,依次执行以下命令 查看根据目录的变化
a.执行compile命令
查看根目录变化 编译程序为.class文件
b.执行clean 命令
清理target文件目录的所有的内容
c.执行clean compile
先执行清理,然后执行编译
d.执行clean test 执行测试程序
执行清理,然后执行测试,如果程序正常 则会提示执行时间、执行结果等信息
如果执行失败,则考虑是maven工程加载的时候缺失一些必要的文件,处理方式:通过另外提供的较完整的respository进行替换原有的内容,重新更新maven工程,等待更新完成再次进行测试即可(由于网络原因可能会导致部分文件在加载的时候没能加载完全,从而导致在使用的时候报错,因此在导入文件的时候要耐心等待,如果加载出错需要将原有的相关目录完全删除,否则再次导入还是无法使用)
此外如果在执行clean compile指令显示错误(无法匹配jre环境,但在cmd窗口下可以执行),则有可能是eclipse中的jdk配置是选择了jre,需要将其修改至相应的jdk即可
e.执行clean package 打包数据
把程序打成jar包,可以供其他项目使用,生成的保存目录参考控制台输出(参考maven输出日志)
项目2:HelloFriend
1>创建Maven工程
创建maven工程参考上述,创建完成需要配置相关属性pom.xml、jre版本
2>如何引用其他工程的内容?
在第二个Maven工程HelloFriend引用Hello工程的内容
a.将指定工程部署到仓库下(Hello工程执行install执行)
执行install命令即可部署,把当前工程部署到到仓库之下,此处仓库路径(C:\Users\Administrator.m2\repository)
部署完成可以在相应的目录查看到相关信息
b.配置pom.xml,将Hello工程引入
在pom.xml中进行配置,配置格式:
<dependency>
<groupId>xxx</groupId>
<artifactId>xxx</artifactId>
<version>xxx</version>
<scope>xxx</scope>
</dependency>
相关参数均可以在Hello工程下的pom.xml文件中查阅,配置如下所示
<dependency>
<groupId>com.noob.maven</groupId>
<artifactId>Hello</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
完成配置点击保存,等待加载完成,刷新工程可以依赖项引入了Hello工程,完成引入则可正常使用Hello工程相关内容
pom.xml依赖配置:
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.noob.maven</groupId>
<artifactId>Hello</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
c.在HelloFriend中引用Hello工程
- HelloFriend.java:
public class HelloFriend {
public String sayHelloFriend(String name) {
// 正常引用Hello工程的内容
Hello hello = new Hello();
return hello.sayHello(name);
}
}
- HelloFriendTest.java:
public class HelloFriendTest {
@Test
public void testHelloFriend() {
// 正常引用Hello工程的内容
HelloFriend hf = new HelloFriend();
String res = hf.sayHelloFriend("张三");
assertEquals(res, "Hello,张三!");
}
}
- 测试结果正常显示:
项目3:MakeFriend
1>a.pom.xml配置
根据上述步骤完成Maven工程创建,在pom.xml中配置相关属性即可(此处引入HelloFriend工程,修改pom.xml相关内容和jre)
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.noob.maven</groupId>
<artifactId>HelloFriend</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
查看工程maven依赖变化,自动将Hello、HelloFriend工程一并导入
2>程序测试
MakeFriend.java:
public class MakeFriend {
public String sayMakeFriend(String name) {
HelloFriend hf = new HelloFriend();
return hf.sayHelloFriend(name);
}
}
MakeFriend.java:
public class MakeFriendTest {
@Test
public void testMakeFriend() {
MakeFriend mf = new MakeFriend();
String res = mf.sayMakeFriend("张三");
assertEquals(res, "Hello,张三!");
}
}
测试结果正常显示
⚡间接依赖和直接依赖
a.在上述内容的基础上,在Hello项目中的pom.xml 添加如下代码,查看Maven Dependencise
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
b.在HelloFriend项目中添加如下代码,查看相应的变化
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
c.在MakeFriend中查看maven的变化
根据结果分析显示在HelloFriend没有引入1.2.17的log4j时,MakeFriend中引用的是1.2.12版本的log4j,在HelloFriend引入1.2.17的log4j后,MakeFriend中的log4j版本相应发生变化,其遵循原则为路径最近者优先
<3>Maven核心概念
Maven的概念模型
Maven的核心仅仅定义了抽象的生命周期,具体的任务都是交由插件完成的
每个插件都能实现多个功能,每个功能就是一个插件目标
Maven的生命周期与插件目标相互绑定,以完成某个具体的构建任务
插件位置:C:\Users\Administrator\.m2\repository\org\apache\maven\plugins
(Maven安装目录)
如果执行clean package 可以看到target包中生成的jar包 里面放置的是.class文件(E:\workspace\JavaEE\Projects\Hello\target)
在pom.xml中配置如下内容
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.2.1</version>
<executions>
<execution>
<goals>
<goal>jar-no-fork</goal>
</goals>
<!--
verify的生命周期在package之后,install之前,
即如果执行package则不会执行verify,但是如果执行install
则一定要执行verify
-->
<phase>
verify
</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
如果执行clean install 可以在指定的目录下看到生成的源码文件
但如果是工程依赖某个外部jar(例如此处MakeFriend依赖HelloFriend、Hello),执行该操作的时候可能会报出找不到相应的依赖jar包问题,要么去除相应的依赖,要么额寻找其他方式解决。在此处测试只是简单利用Hello工程进行测试
在E:\workspace\JavaEE\Projects\Hello\target
目录下查看生成的源码文件
Maven的生命周期
❓何为生命周期?
Maven生命周期就是为了对所有的构建过程进行抽象和统一,包括项目清理,初始化,编译,打包,测试,部署等几乎所有构建步骤
❓Maven三大生命周期
生命周期Maven有三套相互独立的生命周期,请注意这里说的是“三套”,而且“相互独立”,这三套生命周期分别是:
clean:清理项目
default:构建项目
site:生成项目站点
生命周期 | 说明 |
---|---|
clean Lifecycle | 在进行真正的构建之前进行一些清理工作 |
default Lifecycle | 构建的核心部分,编译,测试,打包,部署等等 |
site Lifecycle | 生成项目报告,站点,发布站点 |
❓插件
maven中由插件执行生命周期中相关事件
- 插件与生命周期内的阶段绑定,在执行到对应生命周期时执行对应的插件
- maven默认在各个生命周期上都绑定了预先设定的插件来完成相应功能或者完成自定义功能
# 插件配置参考
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.2.1</version>
<executions>
<execution>
<goals>
<goal>jar</goal>
</goals>
<phase>generate-test-resources</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
1>Clean Lifecycle
clean生命周期每套生命周期都由一组阶段(Phase)组成,平时在命令行输入的命令总会对应于一个特定的阶段。比如,运行mvn clean
,这个的clean是Clean生命周期的一个阶段。有clean生命周期,也有clean阶段。clean生命周期一共包含了三个阶段:
pre-clean 执行一些需要在clean之前完成的工作
clean 移除所有上一次构建生成的文件
post-clean 执行一些需要在clean之后立刻完成的工作
mvn clean中的clean就是上面的clean阶段,在一个生命周期中,运行某个阶段的时候,它之前的所有阶段都会被运行,即mvn clean
等同于 mvn pre-clean clean
,如果运行 mvn post-clean ,那么 pre-clean,clean 都会被运行。这是Maven很重要的一个规则,可以大大简化命令行的输入
2>Default Lifecycle
Default生命周期Default生命周期是Maven生命周期中最重要的一个,绝大部分工作都发生在这个生命周期中。
事件 | 说明 |
---|---|
validate (校验) | 校验项目是否正确并且所有必要的信息可以完成项目的构建过程 |
initialize(初始化) | 初始化构建状态(例如设置属性值) |
generate-sources (生成源代码) | 生成包含在编译阶段中的任何源代码 |
process-sources (处理源代码) | 处理源代码(例如过滤任意值) |
generate-resources (生成资源文件) | 生成将会包含在项目包中的资源文件 |
process-resources (处理资源文件) | 复制并处理资源文件,至目标目录,准备打包 |
compile (编译) | 编译项目的源代码 |
process-classes (处理类文件) | 处理编译生成的文件(例如对Java class文件做字节码改善优化) |
generate-test-sources (生成测试源代码) | 生成包含在编译阶段的任何测试源代码 |
process-test-sources (处理测试源代码) | 处理测试源代码(例如过滤任意值) |
generate-test-resources (生成测试类文件) | 为测试创建资源文件夹 |
process-test-resources(处理资源类文件) | 复制并处理资源文件至目标测试目录 |
test-compile(编译测试源码) | 编译测试源代码至目标测试目录 |
process-test-classes (处理测试类文件) | 处理测试源码编译生成的文件 |
test(测试) | 使用合适的单元测试框架运行测试(这些测试代码不会被打包或部署) |
prepare-package (准备打包) | 在实际打包之前,执行任何必要的操作为打包做准备 |
package(打包) | 接受编译好的代码,打包成可发布的格式,如 JAR |
pre-integration-test (集成测试前) | 在集成测试前进行必要的操作(例如环境搭建) |
integration-test (集成测试) | 处理和部署项目到可以运行集成测试环境中 |
post-integration-test (集成测试后) | 在集成测试之后进行必要的操作(例如清理集成测试环境) |
verify(验证) | 运行任意的检查来验证项目包有效且到达质量标准 |
install(安装) | 将包安装至本地仓库,以让其它项目依赖 |
deploy (部署) | 将最终的包复制到远程的仓库,以让其它开发人员与项目共享 |
对于default生命周期,每个事件在执行之前都会将之前的所有事件依次执行一遍
运行任何一个阶段的时候,它前面的所有阶段都会被运行,这也就是为什么运行mvn install 的时候,代码会被编译,测试,打包。此外,Maven的插件机制是完全依赖Maven的生命周期的,因此理解生命周期至关重要
3>Site Lifecycle
Site生命周期
pre-site:执行一些需要在生成站点文档之前完成的工作
site:生成项目的站点文档
post-site:执行一些需要在生成站点文档之后完成的工作,并且为部署做准备
site-deploy:将生成的站点文档部署到特定的服务器上
经常用到的是site阶段和site-deploy阶段,用以生成和发布Maven站点
通过site可以生成站点信息
# 不需要特殊记忆,每个公司有相应的模板和标准,只需要学会如何使用site指令生成相应的站点信息即可
<!-- 项目信息 -->
<description>xxx项目</description>
<!-- 项目创建年月 -->
<ciManagement>
</ciManagement>
<inceptionYear>2018-1-22</inceptionYear>
<!-- 公司信息 -->
<organization>
<name>百度</name>
<url>http://www.baidu.com/</url>
</organization>
<!-- 研发人员列表 -->
<developers>
<developer>
<id>xxx</id>
<name>小白</name>
<email>xxx@163.com</email>
<roles>
<role>研发经理</role>
<role>研发工程师</role>
</roles>
</developer>
</developers>
<!-- 贡献人列表 -->
<contributors>
<contributor>
<name>小A</name>
<email>xiaoa@163.com</email>
<roles><role>研发工程师</role></roles>
</contributor>
<contributor>
<name>小B</name>
<email>xiaob@163.com</email>
<roles><role>研发工程师</role></roles>
</contributor>
</contributors>
<!-- 许可声明 -->
<licenses>
<license>
<name>许可</name>
<url>http://mis.xxx.cn</url>
<comments>****</comments>
</license>
</licenses>
<!-- 版本控制连接 -->
<scm>
<connection>scm:svn:svn://localhost/test/tags/mis-parent-1.0/test</connection>
<developerConnection>scm:svn:svn://localhost/test/tags/mis-parent-1.0/trunk</developerConnection>
</scm>
<!--问题跟踪系统 -->
<issueManagement>
<system>Streber</system>
<url>http://localhost/index.php</url>
</issueManagement>
可以配置相关的站点信息,但这以配置过程可能时间较长需要耐心等待,且存在问题,使用当前最新版的maven生成站点信息存在问题,可能是由于相关配置的问题还没有得到解决
核心概念
1>坐标
❓什么是坐标?Maven中为何使用坐标?
在平面几何中坐标(x,y)可以标识平面中唯一的一点
maven仓库中存储了各种各样的资源(jar包),通过”坐标”进行定位(坐标用于描述仓库中资源的位置,使用唯一标识定义资源位置,通过该标识可以将资源的识别和下载交由机器完成)
❓Maven坐标主要组成
groupId:定义当前Maven项目隶属项目、组织名称(一般是域名反写:org.mybatis等)
artifactId:定义当前资源名称(一般是项目或者模块名称)
version:定义当前项目的当前版本号信息
packaging:定义该项目的打包方式(jar、war、pom)
2>依赖管理
a.依赖配置
<!-- 管理项目所有依赖 -->
<dependencies>
<!-- 设定具体依赖 -->
<dependency>
<!-- 依赖所属群组ID -->
<groupId>com.noob.maven</groupId>
<!-- 依赖所属项目ID -->
<artifactId>HelloFriend</artifactId>
<!-- 依赖版本号 -->
<version>0.0.1-SNAPSHOT</version>
<!-- 依赖范围 -->
<scope>compile</scope>
</dependency>
</dependencies>
b.依赖传递、冲突问题
依赖传递
直接依赖:在当前项目中通过依赖配置建立的依赖关系
间接依赖:被依赖的资源如果依赖其他资源,则表明当前项目间接依赖其他资源
依赖传递的冲突问题
如果在依赖传递过程中产生了冲突,则参考优先法则
路径优先:当依赖中出现相同资源时,层级越深,优先级越低,反之则越高
声明优先:当资源在相同层级被依赖时,先声明者优先(配置顺序)
特殊优先:当同级配置了相同资源的不同版本时,后配置的覆盖先配置的
c.依赖的范围
依赖范围说明
依赖范围 | 对于主代码 classpath有效 | 对于测试代码 classpath有效 | 被打包、对于运行时有效 | 参考例子 |
---|---|---|---|---|
compile | Y | Y | Y | log4j |
test | - | Y | - | junit |
provided | Y | Y | - | servlet-api |
runtime | - | - | Y | JDBC Driver Implementation |
依赖范围的传递性
带有依赖范围的资源在进行传递时,作用将收到影响
间接依赖\直接依赖 | compile | test | provided | runtime |
---|---|---|---|---|
compile | compile | - | - | runtime |
test | test | - | - | test |
provided | provided | - | provided | provided |
runtime | runtime | - | - | runtime |
d.传递性依赖
案例1:
1)在HelloFriend中的pom.xml中配置
<dependency>
<groupId>com.noob.maven</groupId>
<artifactId>Hello</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
2)在MakeFriend中pom.xml 中配置
<dependency>
<groupId>com.noob.maven</groupId>
<artifactId>HelloFriend</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
3)结合上述依赖传递和作用域影响说明:
# HelloFriend
直接依赖Hello、作用域是compile,因此在HelloFriend中的结构中有Hello
# MakeFriend
MakeFriend和HelloFriend是属于第一直接依赖-->范围Compile
HelloFriend和Hello是属于第二直接依赖-->范围compile
则MakeFriend和Hello是间接依赖,对照范围表其范围为compile,因此MakeFriend项目中的包结构有Hello和HelloFriend
案例2:
1)在HelloFriend中的pom.xml中配置修改
<dependency>
<groupId>com.noob.maven</groupId>
<artifactId>Hello</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>test</scope>
</dependency>
2)在MakeFriend中的pom.xml中配置修改
<dependency>
<groupId>com.noob.maven</groupId>
<artifactId>HelloFriend</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
3)结合上述依赖传递和作用域影响说明
e.可选依赖 、排除依赖
可选依赖 :指对外隐藏当前所依赖的资源(不透明)
在MakeFriend中如果不需要引用Hello这个项目,可以在HelloFriend中通过可选依赖配置不再传递给MakeFriend。在HelloFriend中的pom.xml中可通过optional 标识当前引用不再继续往下传递
<dependency>
<groupId>com.noob.maven</groupId>
<artifactId>Hello</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
排除依赖:指主动断开依赖的资源,被排除的资源无需指定版本(不需要)
如果在MakeFriend中只想引入HelloFriend,而不需要Hello包,可以通过排除依赖配置,在MakeFriend项目中配置
<dependency>
<groupId>com.noob.maven</groupId>
<artifactId>HelloFriend</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
<exclusions>
<exclusion>
<groupId>com.noob.maven</groupId>
<artifactId>Hello</artifactId>
</exclusion>
</exclusions>
</dependency>
3>仓库
仓库概念
maven仓库用于存储资源(各种jar):本地仓库、私服、中央仓库
本地仓库:开发者本地电脑上存储资源的仓库,也可从远程仓库获取资源
私服:各公司/部门等小范围内存储资源的仓库,私服也可以从中央仓库获取资源
- 私服可用于保存具有版权的资源(包含购买或自主研发的jar),在一定内共享资源,能做到仅对内不对外开放
中央仓库:maven团队自身维护的仓库,属于开源的远程仓库
Maven 常用仓库网址:
http://mvnrepository.com/ http://search.maven.org/ http://repository.sonatype.org/content/groups/public/ http://people.apache.org/repo/m2-snapshot-repository/ http://people.apache.org/repo/m2-incubating-repository/
仓库配置
本地仓库配置
maven在本地安装后可以选择在全局进行配置,配置文件settings.xml(【maven安装目录】/conf/settings.xml),其默认的本地仓库配置是在用户名下/.m2/repository
,可通过指定<localRepository>/path/to/local/repo</localRepository>
配置切换本地仓库路径(如果存在多个仓库指向,可copy调整多份settings.xml配置)
远程仓库配置
1)方式1:修改镜像配置(修改settings.xml配置文件)
maven默认连接的仓库是中央仓库(节点在国外,下载访问较慢),可以调整<mirrors>
切换镜像配置为阿里云
<mirror>
<id>nexus-aliyun</id>
<mirrorOf>central</mirrorOf>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
PS:关于镜像比较常用的做法是结合私服搭配使用,由于私服可以代理所有远程仓库(包括中央仓库),因此可以设定访问一个私服即可间接访问所有外部远程仓库
2)方式2:在pomx.ml配置**(仅对当前项目有效)**
<project>
<repositories>
<repository>
<id>aliyun-releases</id>
<url>https://maven.aliyun.com/repository/public</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
</project>
repository元素 | 说明 |
---|---|
id | 远程仓库的标识,中央仓库的id是 central , 添加远程仓库的时候,id不要和中央仓库的id重复,会把中央仓库的覆盖掉 |
url | 远程仓库地址 |
releases | (enabled)配置是否需要从这个远程仓库下载稳定版本构件 |
snapshots | (enabled)配置是否需要从这个远程仓库下载快照版本构件 |
一般使用第三方的仓库,都是下载稳定版本的构件,快照版本的构件以 -SNAPSHOT 结尾,稳定版没有这个标识
<4>Maven的聚合和继承
继承
何为继承?
继承是为了消除重复把很多相同的配置提取出来
例如:grouptId,version等
a.新建工程Parent将公共配置提取并配置相应的内容
- 新建一个Maven工程Parent,修改Pom.xml文件,通过Parent 的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>
<groupId>com.noob.maven</groupId>
<artifactId>Parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Parent</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>com.noob.maven</groupId>
<artifactId>Hello</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.noob.maven</groupId>
<artifactId>HelloFriend</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>
- 在Hello项目中的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>
<artifactId>Hello</artifactId>
<packaging>jar</packaging>
<name>Hello</name>
<url>http://maven.apache.org</url>
<parent>
<groupId>com.noob.maven</groupId>
<artifactId>Parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../Parent/pom.xml</relativePath>
</parent>
</project>
- HelloFriend的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>
<artifactId>HelloFriend</artifactId>
<packaging>jar</packaging>
<name>HelloFriend</name>
<url>http://maven.apache.org</url>
<parent>
<groupId>com.noob.maven</groupId>
<artifactId>Parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../Parent/pom.xml</relativePath>
</parent>
</project>
- 在MakeFriend中的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>
<artifactId>MakeFriend</artifactId>
<packaging>jar</packaging>
<name>MakeFriend</name>
<url>http://maven.apache.org</url>
<parent>
<groupId>com.noob.maven</groupId>
<artifactId>Parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../Parent/pom.xml</relativePath>
</parent>
</project>
b.解决工程配置出错问题
完成上述配置,此时工程会报错(Hello工程下多了HelloFriend依赖)
解决方案:在Parent项目中在<dependencies>......</dependencies>
标签外层多加一层标签为<dependencyManagement></dependencyManagement>
完成配置会看到如下错误,所有的maven依赖都不存在了
进一步进行配置,解决工程配置问题:修改每个项目中的pom.xml依赖
- Hello项目中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>
<artifactId>Hello</artifactId>
<packaging>jar</packaging>
<name>Hello</name>
<url>http://maven.apache.org</url>
<parent>
<groupId>com.noob.maven</groupId>
<artifactId>Parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../Parent/pom.xml</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</dependency>
</dependencies>
</project>
- 修改HelloFriend中的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>
<artifactId>HelloFriend</artifactId>
<packaging>jar</packaging>
<name>HelloFriend</name>
<url>http://maven.apache.org</url>
<parent>
<groupId>com.noob.maven</groupId>
<artifactId>Parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../Parent/pom.xml</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>com.noob.maven</groupId>
<artifactId>Hello</artifactId>
</dependency>
</dependencies>
</project>
- MakeFriend中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>
<artifactId>MakeFriend</artifactId>
<packaging>jar</packaging>
<name>MakeFriend</name>
<url>http://maven.apache.org</url>
<parent>
<groupId>com.noob.maven</groupId>
<artifactId>Parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../Parent/pom.xml</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>com.noob.maven</groupId>
<artifactId>HelloFriend</artifactId>
</dependency>
</dependencies>
</project>
完成上述配置,工程恢复正常:
优点:使用继承是为了统一管理每个使用的jar包的版本。由Parent项目中统一定义版本
缺点:Hello、HelloFriend 、MakeFriend Parent每个项目都需要执行Install安装
聚合
如果想要执行每个子工程都需要:编辑---测试—打包—部署
可以在父工程中统一定义
统一设置属性
<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.noob.maven</groupId>
<artifactId>Parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Parent</name>
<url>http://maven.apache.org</url>
<!-- 执行每个子程序:编辑、测试、打包、部署 -->
<modules>
<module>../Hello</module>
<module>../HelloFriend</module>
<module>../MakeFriend</module>
</modules>
<!-- 此处统一设置属性 -->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<junit-version>4.12</junit-version>
<log4j-version>1.2.17</log4j-version>
<maven-version>0.0.1-SNAPSHOT</maven-version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit-version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j-version}</version>
</dependency>
<dependency>
<groupId>com.noob.maven</groupId>
<artifactId>Hello</artifactId>
<version>${maven-version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.noob.maven</groupId>
<artifactId>HelloFriend</artifactId>
<version>${maven-version}</version>
<scope>compile</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>