Maven高级
1,分模块开发
1.1 分模块开发设计
(1)按照功能拆分
我们现在的项目都是在一个模块中,比如前面的SSM整合开发。虽然这样做功能也都实现了,但是也存在了一些问题,我们拿银行的项目为例来聊聊这个事。
- 网络没有那么发达的时候,我们需要到银行柜台或者取款机进行业务操作
- 随着互联网的发展,我们有了电脑以后,就可以在网页上登录银行网站使用U盾进行业务操作
- 再来就是随着智能手机的普及,我们只需要用手机登录APP就可以进行业务操作
上面三个场景出现的时间是不相同的,如果非要把三个场景的模块代码放入到一个项目,那么当其中某一个模块代码出现问题,就会导致整个项目无法正常启动,从而导致银行的多个业务都无法正常班理。所以我们会按照功能将项目进行拆分。
(2)按照模块拆分
比如电商的项目中,有订单和商品两个模块,订单中需要包含商品的详细信息,所以需要商品的模型类,商品模块也会用到商品的模型类,这个时候如果两个模块中都写模型类,就会出现重复代码,后期的维护成本就比较高。我们就想能不能将它们公共的部分抽取成一个独立的模块,其他模块要想使用可以像添加第三方jar包依赖一样来使用我们自己抽取的模块,这样就解决了代码重复的问题,这种拆分方式就说我们所说的按照模块拆分。
经过两个案例的分析,我们就知道:
- 将原始模块按照功能拆分成若干个子模块,方便模块间的相互调用,接口共享。
刚刚我们说了可以将domain层进行拆分,除了domain层,我们也可以将其他的层也拆成一个个对立的模块,如:
这样的话,项目中的每一层都可以单独维护,也可以很方便的被别人使用。关于分模块开发的意义,我们就说完了,说了这么多好处,那么该如何实现呢?
1.2 分模块开发实现
前面我们已经完成了SSM整合,接下来,咱们就基于SSM整合的项目来实现对项目的拆分。
1.2.1 环境准备
将之前的maven_02_ssm
部署到IDEA中,将环境快速准备好,部署成功后,项目的格式如下:
1.2.2 抽取domain层
步骤1:创建新模块
创建一个名称为maven_03_pojo
的jar项目,为什么项目名是从02到03这样创建,原因后面我们会提到,这块的名称可以任意。
步骤2:项目中创建domain包
在maven_03_pojo
项目中创建com.java.domain
包,并将maven_02_ssm
中Book类拷贝到该包中
步骤3:删除原项目中的domain包
删除后,maven_02_ssm
项目中用到Book
的类中都会有红色提示,如下:
**说明:**出错的原因是maven_02_ssm
中已经将Book类删除,所以该项目找不到Book类,所以报错
要想解决上述问题,我们需要在maven_02_ssm
中添加maven_03_pojo
的依赖。
步骤4:建立依赖关系
在maven_02_ssm
项目的pom.xml添加maven_03_pojo
的依赖
<dependency>
<groupId>com.java</groupId>
<artifactId>maven_03_pojo</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
因为添加了依赖,所以在maven_02_ssm
中就已经能找到Book类,所以刚才的报红提示就会消失。
步骤5:编译maven_02_ssm
项目
编译maven_02_ssm
你会在控制台看到如下错误
错误信息为:不能解决maven_02_ssm
项目的依赖问题,找不到maven_03_pojo
这个jar包。
为什么找不到呢?
原因是Maven会从本地仓库找对应的jar包,但是本地仓库又不存在该jar包所以会报错。
在IDEA中是有maven_03_pojo
这个项目,所以我们只需要将maven_03_pojo
项目安装到本地仓库即可。
步骤6:将项目安装本地仓库
将需要被依赖的项目maven_03_pojo
,使用maven的install命令,把其安装到Maven的本地仓库中。
安装成功后,在对应的路径下就看到安装好的jar包
**说明:**具体安装在哪里,和你们自己电脑上Maven的本地仓库配置的位置有关。
当再次执行maven_02_ssm
的compile的命令后,就已经能够成功编译。
1.2.3 抽取Dao层
步骤1:创建新模块
创建一个名称为maven_04_dao
的jar项目
步骤2:项目中创建dao包
在maven_04_dao
项目中创建com.java.dao
包,并将maven_02_ssm
中BookDao类拷贝到该包中
在maven_04_dao
中会有如下几个问题需要解决下:
-
项目
maven_04_dao
的BookDao接口中Book类找不到报错-
解决方案在
maven_04_dao
项目的pom.xml中添加maven_03_pojo
项目<dependencies> <dependency> <groupId>com.java</groupId> <artifactId>maven_03_pojo</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies>
-
-
项目
maven_04_dao
的BookDao接口中,Mybatis的增删改查注解报错-
解决方案在
maven_04_dao
项目的pom.xml中添加mybatis
的相关依赖<dependencies> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.6</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.47</version> </dependency> </dependencies>
-
步骤3:删除原项目中的dao包
删除Dao包以后,因为maven_02_ssm
中的BookServiceImpl类中有使用到Dao的内容,所以需要在maven_02_ssm
的pom.xml添加maven_04_dao
的依赖
<dependency>
<groupId>com.java</groupId>
<artifactId>maven_04_dao</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
此时在maven_02_ssm
项目中就已经添加了maven_03_pojo
和maven_04_dao
包
再次对maven_02_ssm
项目进行编译,又会报错,如下:
和刚才的错误原因是一样的,maven在仓库中没有找到maven_04_dao
,所以此时我们只需要将maven_04_dao
安装到Maven的本地仓库即可。
步骤4:将项目安装到本地仓库
将需要被依赖的项目maven_04_dao
,使用maven的install命令,把其安装到Maven的本地仓库中。
安装成功后,在对应的路径下就看到了安装好对应的jar包
当再次执行maven_02_ssm
的compile的指令后,就已经能够成功编译。
1.2.4 运行测试并总结
将抽取后的项目进行运行,测试之前的增删改查功能依然能够使用。
所以对于项目的拆分,大致会有如下几个步骤:
(1) 创建Maven模块
(2) 书写模块代码
分模块开发需要先针对模块功能进行设计,再进行编码。不会先将工程开发完毕,然后进行拆分。拆分方式可以按照功能拆也可以按照模块拆。
(3)通过maven指令安装模块到本地仓库(install 指令)
团队内部开发需要发布模块功能到团队内部可共享的仓库中(私服),私服我们后面会讲解。
2,依赖管理
我们现在已经能把项目拆分成一个个独立的模块,当在其他项目中想要使用独立出来的这些模块,只需要在其pom.xml使用标签来进行jar包的引入即可。
其实就是依赖,关于依赖管理里面都涉及哪些内容,我们就一个个来学习下:
- 依赖传递
- 可选依赖
- 排除依赖
我们先来说说什么是依赖:
依赖指当前项目运行所需的jar,一个项目可以设置多个依赖。
格式为:
<!--设置当前项目所依赖的所有jar-->
<dependencies>
<!--设置具体的依赖-->
<dependency>
<!--依赖所属群组id-->
<groupId>org.springframework</groupId>
<!--依赖所属项目id-->
<artifactId>spring-webmvc</artifactId>
<!--依赖版本号-->
<version>5.2.10.RELEASE</version>
</dependency>
</dependencies>
2.1 依赖传递与冲突问题
回到我们刚才的项目案例中,打开Maven的面板,你会发现:
在项目所依赖的这些jar包中,有一个比较大的区别就是有的依赖前面有箭头>
,有的依赖前面没有。
那么这个箭头所代表的含义是什么?
打开前面的箭头,你会发现这个jar包下面还包含有其他的jar包
你会发现有两个maven_03_pojo
的依赖被加载到Dependencies中,那么maven_04_dao
中的maven_03_pojo
能不能使用呢?
要想验证非常简单,只需要把maven_02_ssm
项目中pom.xml关于maven_03_pojo
的依赖注释或删除掉
在Dependencies中移除自己所添加maven_03_pojo
依赖后,打开BookServiceImpl的类,你会发现Book类依然存在,可以被正常使用
这个特性其实就是我们要讲解的依赖传递。
依赖是具有传递性的:
**说明:**A代表自己的项目;B,C,D,E,F,G代表的是项目所依赖的jar包;D1和D2 E1和E2代表是相同jar包的不同版本
(1) A依赖了B和C,B和C有分别依赖了其他jar包,所以在A项目中就可以使用上面所有jar包,这就是所说的依赖传递
(2) 依赖传递有直接依赖和间接依赖
- 相对于A来说,A直接依赖B和C,间接依赖了D1,E1,G,F,D2和E2
- 相对于B来说,B直接依赖了D1和E1,间接依赖了G
- 直接依赖和间接依赖是一个相对的概念
(3)因为有依赖传递的存在,就会导致jar包在依赖的过程中出现冲突问题,具体什么是冲突?Maven是如何解决冲突的?
这里所说的依赖冲突是指项目依赖的某一个jar包,有多个不同的版本,因而造成类包版本冲突。
情况一: 在maven_02_ssm
的pom.xml中添加两个不同版本的Junit依赖:
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
通过对比,会发现一个结论
- 特殊优先:当同级配置了相同资源的不同版本,后配置的覆盖先配置的。
情况二: 路径优先:当依赖中出现相同的资源时,层级越深,优先级越低,层级越浅,优先级越高
- A通过B间接依赖到E1
- A通过C间接依赖到E2
- A就会间接依赖到E1和E2,Maven会按照层级来选择,E1是2度,E2是3度,所以最终会选择E1
情况三: 声明优先:当资源在相同层级被依赖时,配置顺序靠前的覆盖配置顺序靠后的
- A通过B间接依赖到D1
- A通过C间接依赖到D2
- D1和D2都是两度,这个时候就不能按照层级来选择,需要按照声明来,谁先声明用谁,也就是说B在C之前声明,这个时候使用的是D1,反之则为D2
但是对应上面这些结果,大家不需要刻意去记它。因为不管Maven怎么选,最终的结果都会在Maven的Dependencies
面板中展示出来,展示的是哪个版本,也就是说它选择的就是哪个版本,如:
如果想更全面的查看Maven中各个坐标的依赖关系,可以点击Maven面板中的show Dependencies
在这个视图中就能很明显的展示出jar包之间的相互依赖关系。
2.2 可选依赖和排除依赖
依赖传递介绍完以后,我们来思考一个问题,
- maven_02_ssm 依赖了 maven_04_dao
- maven_04_dao 依赖了 maven_03_pojo
- 因为现在有依赖传递,所以maven_02_ssm能够使用到maven_03_pojo的内容
- 如果说现在不想让maven_02_ssm依赖到maven_03_pojo,有哪些解决方案?
**说明:**在真实使用的过程中,maven_02_ssm中是需要用到maven_03_pojo的,我们这里只是用这个例子描述我们的需求。因为有时候,maven_04_dao出于某些因素的考虑,就是不想让别人使用自己所依赖的maven_03_pojo。
方案一:可选依赖
- 可选依赖指对外隐藏当前所依赖的资源—不透明
在maven_04_dao
的pom.xml,在引入maven_03_pojo
的时候,添加optional
<dependency>
<groupId>com.java</groupId>
<artifactId>maven_03_pojo</artifactId>
<version>1.0-SNAPSHOT</version>
<!--可选依赖是隐藏当前工程所依赖的资源,隐藏后对应资源将不具有依赖传递-->
<optional>true</optional>
</dependency>
此时BookServiceImpl就已经报错了,说明由于maven_04_dao将maven_03_pojo设置成可选依赖,导致maven_02_ssm无法引用到maven_03_pojo中的内容,导致Book类找不到。
方案二:排除依赖
- 排除依赖指主动断开依赖的资源,被排除的资源无需指定版本—不需要
前面我们已经通过可选依赖实现了阻断maven_03_pojo的依赖传递,对于排除依赖,则指的是已经有依赖的事实,也就是说maven_02_ssm项目中已经通过依赖传递用到了maven_03_pojo,此时我们需要做的是将其进行排除,所以接下来需要修改maven_02_ssm的pom.xml
<dependency>
<groupId>com.java</groupId>
<artifactId>maven_04_dao</artifactId>
<version>1.0-SNAPSHOT</version>
<!--排除依赖是隐藏当前资源对应的依赖关系-->
<exclusions>
<exclusion>
<groupId>com.java</groupId>
<artifactId>maven_03_pojo</artifactId>
</exclusion>
</exclusions>
</dependency>
这样操作后,BookServiceImpl中的Book类一样也会报错。
当然exclusions
标签带s
说明我们是可以依次排除多个依赖到的jar包,比如maven_04_dao中有依赖junit和mybatis,我们也可以一并将其排除。
<dependency>
<groupId>com.java</groupId>
<artifactId>maven_04_dao</artifactId>
<version>1.0-SNAPSHOT</version>
<!--排除依赖是隐藏当前资源对应的依赖关系-->
<exclusions>
<exclusion>
<groupId>com.java</groupId>
<artifactId>maven_03_pojo</artifactId>
</exclusion>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
<exclusion>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
</exclusion>
</exclusions>
</dependency>
介绍我这两种方式后,简单来梳理下,就是
A依赖B,B依赖C
,C
通过依赖传递会被A
使用到,现在要想办法让A
不去依赖C
- 可选依赖是在B上设置
<optional>
,A
不知道有C
的存在, - 排除依赖是在A上设置
<exclusions>
,A
知道有C
的存在,主动将其排除掉。
3,聚合和继承
我们的项目已经从以前的单模块,变成了现在的多模块开发。项目一旦变成了多模块开发以后,就会引发一些问题,在这一节中我们主要会学习两个内容聚合
和继承
,用这两个知识来解决下分模块后的一些问题。
3.1 聚合
- 分模块开发后,需要将这四个项目都安装到本地仓库,目前我们只能通过项目Maven面板的
install
来安装,并且需要安装四个,如果我们的项目足够多,那么一个个安装起来还是比较麻烦的 - 如果四个项目都已经安装成功,当ssm_pojo发生变化后,我们就得将ssm_pojo重新安装到maven仓库,但是为了确保我们对ssm_pojo的修改不会影响到其他项目模块,我们需要对所有的模块进行重新编译,那又需要将所有的模块再来一遍
项目少的话还好,但是如果项目多的话,一个个操作项目就容易出现漏掉或重复操作的问题,所以我们就想能不能抽取一个项目,把所有的项目管理起来,以后我们要想操作这些项目,只需要操作这一个项目,其他所有的项目都走一样的流程,这个不就很省事省力。
这就用到了我们接下来要讲解的聚合,
- 所谓聚合:将多个模块组织成一个整体,同时进行项目构建的过程称为聚合
- 聚合工程:通常是一个不具有业务功能的"空"工程(有且仅有一个pom文件)
- 作用:使用聚合工程可以将多个工程编组,通过对聚合工程进行构建,实现对所包含的模块进行同步构建
- 当工程中某个模块发生更新(变更)时,必须保障工程中与已更新模块关联的模块同步更新,此时可以使用聚合工程来解决批量模块同步构建的问题。
关于聚合具体的实现步骤为:
步骤1:创建一个空的maven项目
步骤2:将项目的打包方式改为pom
<?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.java</groupId>
<artifactId>maven_01_parent</artifactId>
<version>1.0-RELEASE</version>
<packaging>pom</packaging>
</project>
**说明:**项目的打包方式,我们接触到的有三种,分别是
- jar:默认情况,说明该项目为java项目
- war:说明该项目为web项目
- pom:说明该项目为聚合或继承(后面会讲)项目
步骤3:pom.xml添加所要管理的项目
<?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.java</groupId>
<artifactId>maven_01_parent</artifactId>
<version>1.0-RELEASE</version>
<packaging>pom</packaging>
<!--设置管理的模块名称-->
<modules>
<module>../maven_02_ssm</module>
<module>../maven_03_pojo</module>
<module>../maven_04_dao</module>
</modules>
</project>
步骤4:使用聚合统一管理项目
测试发现,当maven_01_parent
的compile
被点击后,所有被其管理的项目都会被执行编译操作。这就是聚合工程的作用。
**说明:**聚合工程管理的项目在进行运行的时候,会按照项目与项目之间的依赖关系来自动决定执行的顺序和配置的顺序无关。
聚合的知识我们就讲解完了,最后总结一句话就是,聚合工程主要是用来管理项目。
3.2 继承
我们已经完成了使用聚合工程去管理项目,聚合工程进行某一个构建操作,其他被其管理的项目也会执行相同的构建操作。那么接下来,我们再来分析下,多模块开发存在的另外一个问题,重复配置
的问题,我们先来看张图:
spring-webmvc
、spring-jdbc
在三个项目模块中都有出现,这样就出现了重复的内容spring-test
只在ssm_crm和ssm_goods中出现,而在ssm_order中没有,这里是部分重复的内容- 我们使用的spring版本目前是
5.2.10.RELEASE
,假如后期要想升级spring版本,所有跟Spring相关jar包都得被修改,涉及到的项目越多,维护成本越高
面对上面的这些问题,我们就得用到接下来要学习的继承
- 所谓继承:描述的是两个工程间的关系,与java中的继承相似,子工程可以继承父工程中的配置信息,常见于依赖关系的继承。
- 作用:
- 简化配置
- 减少版本冲突
接下来,我们到程序中去看看继承该如何实现?
步骤1:创建一个空的Maven项目并将其打包方式设置为pom
因为这一步和前面maven创建聚合工程的方式是一摸一样,所以我们可以单独创建一个新的工程,也可以直接和聚合公用一个工程。实际开发中,聚合和继承一般也都放在同一个项目中,但是这两个的功能是不一样的。
步骤2:在子项目中设置其父工程
分别在maven_02_ssm
,maven_03_pojo
,maven_04_dao
的pom.xml中添加其父项目为maven_01_parent
<!--配置当前工程继承自parent工程-->
<parent>
<groupId>com.java</groupId>
<artifactId>maven_01_parent</artifactId>
<version>1.0-RELEASE</version>
<!--设置父项目pom.xml位置路径-->
<relativePath>../maven_01_parent/pom.xml</relativePath>
</parent>
步骤3:优化子项目共有依赖导入问题
- 将子项目共同使用的jar包都抽取出来,维护在父项目的pom.xml中
<?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.java</groupId>
<artifactId>maven_01_parent</artifactId>
<version>1.0-RELEASE</version>
<packaging>pom</packaging>
<!--设置管理的模块名称-->
<modules>
<module>../maven_02_ssm</module>
<module>../maven_03_pojo</module>
<module>../maven_04_dao</module>
</modules>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.6</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.16</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
</dependencies>
</project>
- 删除子项目中已经被抽取到父项目的pom.xml中的jar包,如在
maven_02_ssm
的pom.xml中将已经出现在父项目的jar包删除掉
<?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.java</groupId>
<artifactId>maven_02_ssm</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<!--配置当前工程继承自parent工程-->
<parent>
<groupId>com.java</groupId>
<artifactId>maven_01_parent</artifactId>
<version>1.0-RELEASE</version>
<relativePath>../maven_01_parent/pom.xml</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.java</groupId>
<artifactId>maven_04_dao</artifactId>
<version>1.0-SNAPSHOT</version>
<!--排除依赖是隐藏当前资源对应的依赖关系-->
<exclusions>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
<exclusion>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.1</version>
<configuration>
<port>80</port>
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>
</project>
删除完后,你会发现父项目中有依赖对应的jar包,子项目虽然已经将重复的依赖删除掉了,但是刷新的时候,子项目中所需要的jar包依然存在。
当项目的<parent>
标签被移除掉,会发现多出来的jar包依赖也会随之消失。
- 将
maven_04_dao
项目的pom.xml中的所有依赖删除,然后添加上maven_01_parent
的父项目坐标
<?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.java</groupId>
<artifactId>maven_04_dao</artifactId>
<version>1.0-SNAPSHOT</version>
<!--配置当前工程继承自parent工程-->
<parent>
<groupId>com.java</groupId>
<artifactId>maven_01_parent</artifactId>
<version>1.0-RELEASE</version>
<relativePath>../maven_01_parent/pom.xml</relativePath>
</parent>
</project>
刷新并查看Maven的面板,会发现maven_04_dao同样引入了父项目中的所有依赖。
这样我们就可以解决刚才提到的第一个问题,将子项目中的公共jar包抽取到父工程中进行统一添加依赖,这样做的可以简化配置,并且当父工程中所依赖的jar包版本发生变化,所有子项目中对应的jar包版本也会跟着更新。
步骤4:优化子项目依赖版本问题
如果把所有用到的jar包都管理在父项目的pom.xml,看上去更简单些,但是这样就会导致有很多项目引入了过多自己不需要的jar包。如上面看到的这张图:
如果把所有的依赖都放在了父工程中进行统一维护,就会导致ssm_order项目中多引入了spring-test
的jar包,如果这样的jar包过多的话,对于ssm_order来说也是一种"负担"。
那针对于这种部分项目有的jar包,我们该如何管理优化呢?
- 在父工程mavne_01_parent的pom.xml来定义依赖管理
<!--定义依赖管理-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement>
- 将maven_02_ssm的pom.xml中的junit依赖删除掉,刷新Maven
刷新完会发现,在maven_02_ssm项目中的junit依赖并没有出现,所以我们得到一个结论:
<dependencyManagement>
标签不真正引入jar包,而是配置可供子项目选择的jar包依赖
子项目要想使用它所提供的这些jar包,需要自己添加依赖,并且不需要指定<version>
- 在maven_02_ssm的pom.xml添加junit的依赖
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
注意:这里就不需要添加版本了,这样做的好处就是当父工程dependencyManagement标签中的版本发生变化后,子项目中的依赖版本也会跟着发生变化
- 在maven_04_dao的pom.xml添加junit的依赖
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
这个时候,maven_02_ssm和maven_04_dao这两个项目中的junit版本就会跟随着父项目中的标签dependencyManagement中junit的版本发生变化而变化。不需要junit的项目就不需要添加对应的依赖即可。
至此继承就已经学习完了,总结来说,继承可以帮助做两件事
- 将所有项目公共的jar包依赖提取到父工程的pom.xml中,子项目就可以不用重复编写,简化开发
- 将所有项目的jar包配置到父工程的dependencyManagement标签下,实现版本管理,方便维护
- dependencyManagement标签不真正引入jar包,只是管理jar包的版本
- 子项目在引入的时候,只需要指定groupId和artifactId,不需要加version
- 当dependencyManagement标签中jar包版本发生变化,所有子项目中有用到该jar包的地方对应的版本会自动随之更新
最后总结一句话就是,父工程主要是用来快速配置依赖jar包和管理项目中所使用的资源。
小结
继承的实现步骤:
-
创建Maven模块,设置打包类型为pom
<packaging>pom</packaging>
-
在父工程的pom文件中配置依赖关系(子工程将沿用父工程中的依赖关系),一般只抽取子项目中公有的jar包
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.10.RELEASE</version> </dependency> ... </dependencies>
-
在父工程中配置子工程中可选的依赖关系
<dependencyManagement> <dependencies> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.16</version> </dependency> </dependencies> ... </dependencyManagement>
-
在子工程中配置当前工程所继承的父工程
<!--定义该工程的父工程--> <parent> <groupId>com.java</groupId> <artifactId>maven_01_parent</artifactId> <version>1.0-RELEASE</version> <!--填写父工程的pom文件,可以不写--> <relativePath>../maven_01_parent/pom.xml</relativePath> </parent>
-
在子工程中配置使用父工程中可选依赖的坐标
<dependencies> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> </dependency> </dependencies>
注意事项:
1.子工程中使用父工程中的可选依赖时,仅需要提供群组id和项目id,无需提供版本,版本由父工程统一提供,避免版本冲突
2.子工程中还可以定义父工程中没有定义的依赖关系,只不过不能被父工程进行版本统一管理。
3.3 聚合与继承的区别
3.3.1 聚合与继承的区别
两种之间的作用:
- 聚合用于快速构建项目,对项目进行管理
- 继承用于快速配置和管理子项目中所使用jar包的版本
聚合和继承的相同点:
- 聚合与继承的pom.xml文件打包方式均为pom,可以将两种关系制作到同一个pom文件中
- 聚合与继承均属于设计型模块,并无实际的模块内容
聚合和继承的不同点:
- 聚合是在当前模块中配置关系,聚合可以感知到参与聚合的模块有哪些
- 继承是在子模块中配置关系,父模块无法感知哪些子模块继承了自己
相信到这里,大家已经能区分开什么是聚合和继承,但是有一个稍微麻烦的地方就是聚合和继承的工程构建,需要在聚合项目中手动添加modules
标签,需要在所有的子项目中添加parent
标签,万一写错了咋办?
3.3.2 IDEA构建聚合与继承工程
其实对于聚合和继承工程的创建,IDEA已经能帮助我们快速构建,具体的实现步骤为:
步骤1:创建一个Maven项目
创建一个空的Maven项目,可以将项目中的src
目录删除掉,这个项目作为聚合工程和父工程。
步骤2:创建子项目
该项目可以被聚合工程管理,同时会继承父工程。
创建成功后,maven_parent即是聚合工程又是父工程,maven_web中也有parent标签,继承的就是maven_parent,对于难以配置的内容都自动生成。
按照上面这种方式,大家就可以根据自己的需要来构建分模块项目。
4,属性
在这一章节内容中,我们将学习两个内容,分别是
- 属性
- 版本管理
属性中会继续解决分模块开发项目存在的问题,版本管理主要是认识下当前主流的版本定义方式。
4.1 属性
4.1.1 问题分析
讲解内容之前,我们还是先来分析问题:
前面我们已经在父工程中的dependencyManagement标签中对项目中所使用的jar包版本进行了统一的管理,但是如果在标签中有如下的内容:
你会发现,如果我们现在想更新Spring的版本,你会发现我们依然需要更新多个jar包的版本,这样的话还是有可能出现漏改导致程序出问题,而且改起来也是比较麻烦。
问题清楚后,我们需要解决的话,就可以参考咱们java基础所学习的变量,声明一个变量,在其他地方使用该变量,当变量的值发生变化后,所有使用变量的地方,就会跟着修改,即:
4.1.2 解决步骤
步骤1:父工程中定义属性
<properties>
<spring.version>5.2.10.RELEASE</spring.version>
<junit.version>4.12</junit.version>
<mybatis-spring.version>1.3.0</mybatis-spring.version>
</properties>
步骤2:修改依赖的version
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
此时,我们只需要更新父工程中properties标签中所维护的jar包版本,所有子项目中的版本也就跟着更新。当然除了将spring相关版本进行维护,我们可以将其他的jar包版本也进行抽取,这样就可以对项目中所有jar包的版本进行统一维护,如:
<!--定义属性-->
<properties>
<spring.version>5.2.10.RELEASE</spring.version>
<junit.version>4.12</junit.version>
<mybatis-spring.version>1.3.0</mybatis-spring.version>
</properties>
4.2 配置文件加载属性
Maven中的属性我们已经介绍过了,现在也已经能够通过Maven来集中管理Maven中依赖jar包的版本。但是又有新的需求,就是想让Maven对于属性的管理范围能更大些,比如我们之前项目中的jdbc.properties
,这个配置文件中的属性,能不能也来让Maven进行管理呢?
答案是肯定的,具体的实现步骤为:
步骤1:父工程定义属性
<properties>
<jdbc.url>jdbc:mysql://127.1.1.1:3306/ssm_db</jdbc.url>
</properties>
步骤2:jdbc.properties文件中引用属性
在jdbc.properties,将jdbc.url的值直接获取Maven配置的属性
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=${jdbc.url}
jdbc.username=root
jdbc.password=root
步骤3:设置maven过滤文件范围
Maven在默认情况下是从当前项目的src\main\resources
下读取文件进行打包。现在我们需要打包的资源文件是在maven_02_ssm下,需要我们通过配置来指定下具体的资源目录。
<build>
<resources>
<!--设置资源目录-->
<resource>
<directory>../maven_02_ssm/src/main/resources</directory>
<!--设置能够解析${},默认是false -->
<filtering>true</filtering>
</resource>
</resources>
</build>
**说明:**directory路径前要添加../
的原因是maven_02_ssm相对于父工程的pom.xml路径是在其上一层的目录中,所以需要添加。
修改完后,注意maven_02_ssm项目的resources目录就多了些东西,如下:
步骤4:测试是否生效
测试的时候,只需要将maven_02_ssm项目进行打包,然后观察打包结果中最终生成的内容是否为Maven中配置的内容。
上面的属性管理就已经完成,但是有一个问题没有解决,因为不只是maven_02_ssm项目需要有属性被父工程管理,如果有多个项目需要配置,该如何实现呢?
方式一:
<build>
<resources>
<!--设置资源目录,并设置能够解析${}-->
<resource>
<directory>../maven_02_ssm/src/main/resources</directory>
<filtering>true</filtering>
</resource>
<resource>
<directory>../maven_03_pojo/src/main/resources</directory>
<filtering>true</filtering>
</resource>
...
</resources>
</build>
可以配,但是如果项目够多的话,这个配置也是比较繁琐
方式二:
<build>
<resources>
<!--
${project.basedir}: 当前项目所在目录,子项目继承了父项目,
相当于所有的子项目都添加了资源目录的过滤
-->
<resource>
<directory>${project.basedir}/src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
**说明:**打包的过程中如果报如下错误:
原因就是Maven发现你的项目为web项目,就会去找web项目的入口web.xml[配置文件配置的方式],发现没有找到,就会报错。
解决方案1:在maven_02_ssm项目的src\main\webapp\WEB-INF\
添加一个web.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
</web-app>
解决方案2: 配置maven打包war时,忽略web.xml检查
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.3</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
上面我们所使用的都是Maven的自定义属性,除了${project.basedir},它属于Maven的内置系统属性。
在Maven中的属性分为:
- 自定义属性(常用)
- 内置属性
- Setting属性
- Java系统属性
- 环境变量属性
具体如何查看这些属性:
在cmd命令行中输入mvn help:system
具体使用,就是使用 ${key}
来获取,key为等号左边的,值为等号右边的,比如获取红线的值,对应的写法为 ${java.runtime.name}
。
4.3 版本管理
关于这个版本管理解决的问题是,在Maven创建项目和引用别人项目的时候,我们都看到过如下内容:
这里面有两个单词,SNAPSHOT和RELEASE,它们所代表的含义是什么呢?
我们打开Maven仓库地址https://mvnrepository.com/
在我们jar包的版本定义中,有两个工程版本用的比较多:
- SNAPSHOT(快照版本)
- 项目开发过程中临时输出的版本,称为快照版本
- 快照版本会随着开发的进展不断更新
- RELEASE(发布版本)
- 项目开发到一定阶段里程碑后,向团队外部发布较为稳定的版本,这种版本所对应的构件文件是稳定的
- 即便进行功能的后续开发,也不会改变当前发布版本内容,这种版本称为发布版本
除了上面的工程版本,我们还经常能看到一些发布版本:
- alpha版:内测版,bug多不稳定内部版本不断添加新功能
- beta版:公测版,不稳定(比alpha稳定些),bug相对较多不断添加新功能
- 纯数字版
对于这些版本,大家只需要简单认识下即可。
5,多环境配置与应用
这一节中,我们会讲两个内容,分别是多环境开发
和跳过测试
5.1 多环境开发
- 我们平常都是在自己的开发环境进行开发,
- 当开发完成后,需要把开发的功能部署到测试环境供测试人员进行测试使用,
- 等测试人员测试通过后,我们会将项目部署到生成环境上线使用。
- 这个时候就有一个问题是,不同环境的配置是不相同的,如不可能让三个环境都用一个数据库,所以就会有三个数据库的url配置,
- 我们在项目中如何配置?
- 要想实现不同环境之间的配置切换又该如何来实现呢?
maven提供配置多种环境的设定,帮助开发者在使用过程中快速切换环境。具体实现步骤:
步骤1:父工程配置多个环境,并指定默认激活环境
<profiles>
<!--开发环境-->
<profile>
<id>env_dep</id>
<properties>
<jdbc.url>jdbc:mysql://127.1.1.1:3306/ssm_db</jdbc.url>
</properties>
<!--设定是否为默认启动环境-->
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<!--生产环境-->
<profile>
<id>env_pro</id>
<properties>
<jdbc.url>jdbc:mysql://127.2.2.2:3306/ssm_db</jdbc.url>
</properties>
</profile>
<!--测试环境-->
<profile>
<id>env_test</id>
<properties>
<jdbc.url>jdbc:mysql://127.3.3.3:3306/ssm_db</jdbc.url>
</properties>
</profile>
</profiles>
步骤2:执行安装查看env_dep环境是否生效
查看到的结果为:
步骤3:切换默认环境为生产环境
<profiles>
<!--开发环境-->
<profile>
<id>env_dep</id>
<properties>
<jdbc.url>jdbc:mysql://127.1.1.1:3306/ssm_db</jdbc.url>
</properties>
</profile>
<!--生产环境-->
<profile>
<id>env_pro</id>
<properties>
<jdbc.url>jdbc:mysql://127.2.2.2:3306/ssm_db</jdbc.url>
</properties>
<!--设定是否为默认启动环境-->
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<!--测试环境-->
<profile>
<id>env_test</id>
<properties>
<jdbc.url>jdbc:mysql://127.3.3.3:3306/ssm_db</jdbc.url>
</properties>
</profile>
</profiles>
步骤4:执行安装并查看env_pro环境是否生效
查看到的结果为jdbc:mysql://127.2.2.2:3306/ssm_db
虽然已经能够实现不同环境的切换,但是每次切换都是需要手动修改,如何来实现在不改变代码的前提下完成环境的切换呢?
步骤5:命令行实现环境切换
步骤6:执行安装并查看env_test环境是否生效
查看到的结果为jdbc:mysql://127.3.3.3:3306/ssm_db
所以总结来说,对于多环境切换只需要两步即可:
-
父工程中定义多环境
<profiles> <profile> <id>环境名称</id> <properties> <key>value</key> </properties> <activation> <activeByDefault>true</activeByDefault> </activation> </profile> ... </profiles>
-
使用多环境(构建过程)
mvn 指令 -P 环境定义ID[环境定义中获取]
5.2 跳过测试
前面在执行install
指令的时候,Maven都会按照顺序从上往下依次执行,每次都会执行test
,
对于test
来说有它存在的意义,
- 可以确保每次打包或者安装的时候,程序的正确性,假如测试已经通过在我们没有修改程序的前提下再次执行打包或安装命令,由于顺序执行,测试会被再次执行,就有点耗费时间了。
- 功能开发过程中有部分模块还没有开发完毕,测试无法通过,但是想要把其中某一部分进行快速打包,此时由于测试环境失败就会导致打包失败。
遇到上面这些情况的时候,我们就想跳过测试执行下面的构建命令,具体实现方式有很多:
方式一:IDEA工具实现跳过测试
图中的按钮为Toggle 'Skip Tests' Mode
,
Toggle翻译为切换的意思,也就是说在测试与不测试之间进行切换。
点击一下,出现测试画横线的图片,如下:
说明测试已经被关闭,再次点击就会恢复。
这种方式最简单,但是有点"暴力",会把所有的测试都跳过,如果我们想更精细的控制哪些跳过哪些不跳过,就需要使用配置插件的方式。
方式二:配置插件实现跳过测试
在父工程中的pom.xml中添加测试插件配置
<build>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12.4</version>
<configuration>
<skipTests>false</skipTests>
<!--排除掉不参与测试的内容-->
<excludes>
<exclude>**/BookServiceTest.java</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
skipTests:如果为true,则跳过所有测试,如果为false,则不跳过测试
excludes:哪些测试类不参与测试,即排除,针对skipTests为false来设置的
includes: 哪些测试类要参与测试,即包含,针对skipTests为true来设置的
方式三:命令行跳过测试
使用Maven的命令行,mvn 指令 -D skipTests
注意事项:
- 执行的项目构建指令必须包含测试生命周期,否则无效果。例如执行compile生命周期,不经过test生命周期。
- 该命令可以不借助IDEA,直接使用cmd命令行进行跳过测试,需要注意的是cmd要在pom.xml所在目录下进行执行。
6,私服
这一节,我们主要学习的内容是:
- 私服简介
- 私服仓库分类
- 资源上传与下载
首先来说一说什么是私服?
6.1 私服简介
团队开发现状分析
(1)张三负责ssm_crm的开发,自己写了一个ssm_pojo模块,要想使用直接将ssm_pojo安装到本地仓库即可
(2)李四负责ssm_order的开发,需要用到张三所写的ssm_pojo模块,这个时候如何将张三写的ssm_pojo模块交给李四呢?
(3)如果直接拷贝,那么团队之间的jar包管理会非常混乱而且容器出错,这个时候我们就想能不能将写好的项目上传到中央仓库,谁想用就直接联网下载即可
(4)Maven的中央仓库不允许私人上传自己的jar包,那么我们就得换种思路,自己搭建一个类似于中央仓库的东西,把自己的内容上传上去,其他人就可以从上面下载jar包使用
(5)这个类似于中央仓库的东西就是我们接下来要学习的私服
所以到这就有两个概念,一个是私服,一个是中央仓库
私服:公司内部搭建的用于存储Maven资源的服务器
远程仓库:Maven开发团队维护的用于存储Maven资源的服务器
所以说:
- 私服是一台独立的服务器,用于解决团队内部的资源共享与资源同步问题
搭建Maven私服的方式有很多,我们来介绍其中一种使用量比较大的实现方式:
- Nexus
- Sonatype公司的一款maven私服产品
- 下载地址:https://help.sonatype.com/repomanager3/download
6.2 私服安装
步骤1:下载解压
将atest-win64.zip
解压到一个空目录下。
注意:sonatype-work文件夹一定要拷贝
步骤2:启动Nexus
使用cmd进入到解压目录下的nexus-3.30.1-01\bin
,执行如下命令:
nexus.exe /run nexus
看到如下内容,说明启动成功。
步骤3:浏览器访问
访问地址为:
http://localhost:8081
步骤4:首次登录重置密码
输入用户名和密码进行登录,登录成功后,出现如下页面
点击下一步,需要重新输入新密码,为了和后面的保持一致,密码修改为admin
设置是否运行匿名访问
点击完成
至此私服就已经安装成功。如果要想修改一些基础配置信息,可以使用:
- 修改基础配置信息
- 安装路径下etc目录中nexus-default.properties文件保存有nexus基础配置信息,例如默认访问端口。
- 修改服务器运行配置信息
- 安装路径下bin目录中nexus.vmoptions文件保存有nexus服务器启动对应的配置信息,例如默认占用内存空间。
6.3 私服仓库分类
私服资源操作流程分析:
(1)在没有私服的情况下,我们自己创建的服务都是安装在Maven的本地仓库中
(2)私服中也有仓库,我们要把自己的资源上传到私服,最终也是放在私服的仓库中
(3)其他人要想使用你所上传的资源,就需要从私服的仓库中获取
(4)当我们要使用的资源不是自己写的,是远程中央仓库有的第三方jar包,这个时候就需要从远程中央仓库下载,每个开发者都去远程中央仓库下速度比较慢(中央仓库服务器在国外)
(5)私服就再准备一个仓库,用来专门存储从远程中央仓库下载的第三方jar包,第一次访问没有就会去远程中央仓库下载,下次再访问就直接走私服下载
(6)前面在介绍版本管理的时候提到过有SNAPSHOT
和RELEASE
,如果把这两类的都放到同一个仓库,比较混乱,所以私服就把这两个种jar包放入不同的仓库
(7)上面我们已经介绍了有三种仓库,一种是存放SNAPSHOT
的,一种是存放RELEASE
还有一种是存放从远程仓库下载的第三方jar包,那么我们在获取资源的时候要从哪个仓库种获取呢?
(8)为了方便获取,我们将所有的仓库编成一个组,我们只需要访问仓库组去获取资源。
所有私服仓库总共分为三大类:
宿主仓库hosted
- 保存无法从中央仓库获取的资源
- 自主研发
- 第三方非开源项目,比如Oracle,因为是付费产品,所以中央仓库没有
代理仓库proxy
- 代理远程仓库,通过nexus访问其他公共仓库,例如中央仓库
仓库组group
- 将若干个仓库组成一个群组,简化配置
- 仓库组不能保存资源,属于设计型仓库
6.4 本地仓库访问私服配置
- 我们通过IDEA将开发的模块上传到私服,中间是要经过本地Maven的
- 本地Maven需要知道私服的访问地址以及私服访问的用户名和密码
- 私服中的仓库很多,Maven最终要把资源上传到哪个仓库?
- Maven下载的时候,又需要携带用户名和密码到私服上找对应的仓库组进行下载,然后再给IDEA
上面所说的这些内容,我们需要在本地Maven的配置文件settings.xml
中进行配置。
步骤1:私服上配置仓库
说明:
第5,6步骤是创建java-snapshot仓库
第7,8步骤是创建java-release仓库
步骤2:配置本地Maven对私服的访问权限
<servers>
<server>
<id>java-snapshot</id>
<username>admin</username>
<password>admin</password>
</server>
<server>
<id>java-release</id>
<username>admin</username>
<password>admin</password>
</server>
</servers>
步骤3:配置私服的访问路径
<mirrors>
<mirror>
<!--配置仓库组的ID-->
<id>maven-public</id>
<!--*代表所有内容都从私服获取-->
<mirrorOf>*</mirrorOf>
<!--私服仓库组maven-public的访问路径-->
<url>http://localhost:8081/repository/maven-public/</url>
</mirror>
</mirrors>
为了避免阿里云Maven私服地址的影响,建议先将之前配置的阿里云Maven私服镜像地址注释掉,等练习完后,再将其恢复。
至此本地仓库就能与私服进行交互了。
6.5 私服资源上传与下载
本地仓库与私服已经建立了连接,接下来我们就需要往私服上上传资源和下载资源,具体的实现步骤为:
步骤1:配置工程上传私服的具体位置
<!--配置当前工程保存在私服中的具体位置-->
<distributionManagement>
<repository>
<!--和maven/settings.xml中server中的id一致,表示使用该id对应的用户名和密码-->
<id>java-release</id>
<!--release版本上传仓库的具体地址-->
<url>http://localhost:8081/repository/java-release/</url>
</repository>
<snapshotRepository>
<!--和maven/settings.xml中server中的id一致,表示使用该id对应的用户名和密码-->
<id>java-snapshot</id>
<!--snapshot版本上传仓库的具体地址-->
<url>http://localhost:8081/repository/java-snapshot/</url>
</snapshotRepository>
</distributionManagement>
步骤2:发布资源到私服
或者执行Maven命令
mvn deploy
注意:
要发布的项目都需要配置distributionManagement
标签,要么在自己的pom.xml中配置,要么在其父项目中配置,然后子项目中继承父项目即可。
发布成功,在私服中就能看到:
现在发布是在java-snapshot仓库中,如果想发布到java-release仓库中就需要将项目pom.xml中的version修改成RELEASE即可。
如果想删除已经上传的资源,可以在界面上进行删除操作:
如果私服中没有对应的jar,会去中央仓库下载,速度很慢。可以配置让私服去阿里云中下载依赖。
至此私服的搭建就已经完成,相对来说有点麻烦,但是步骤都比较固定,后期大家如果需要的话,就可以参考上面的步骤一步步完成搭建即可。
附件1:POM文件总体配置说明
<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/maven-v4_0_0.xsd ">
<!-- 父项目的坐标。如果项目中没有规定某个元素的值,那么父项目中的对应值即为项目的默认值。
坐标包括group ID,artifact ID和 version。 -->
<parent>
<!-- 被继承的父项目的构件标识符 -->
<artifactId>xxx</artifactId>
<!-- 被继承的父项目的全球唯一标识符 -->
<groupId>xxx</groupId>
<!-- 被继承的父项目的版本 -->
<version>xxx</version>
<!-- 父项目的pom.xml文件的相对路径。相对路径允许你选择一个不同的路径。默认值是../pom.xml。
Maven首先在构建当前项目的地方寻找父项目的pom,其次在文件系统的这个位置(relativePath位置),
然后在本地仓库,最后在远程仓库寻找父项目的pom。 -->
<relativePath>xxx</relativePath>
</parent>
<!-- 声明项目描述符遵循哪一个POM模型版本。模型本身的版本很少改变,虽然如此,但它仍然是必不可少的,
这是为了当Maven引入了新的特性或者其他模型变更的时候,确保稳定性。 -->
<modelVersion> 4.0.0 </modelVersion>
<!-- 项目的全球唯一标识符,通常使用全限定的包名区分该项目和其他项目。并且构建时生成的路径也是由此生成,
如com.mycompany.app生成的相对路径为:/com/mycompany/app -->
<groupId>xxx</groupId>
<!-- 构件的标识符,它和group ID一起唯一标识一个构件。换句话说,你不能有两个不同的项目拥有同样的artifact ID
和groupID;在某个特定的group ID下,artifact ID也必须是唯一的。构件是项目产生的或使用的一个东西,Maven
为项目产生的构件包括:JARs,源码,二进制发布和WARs等。 -->
<artifactId>xxx</artifactId>
<!-- 项目产生的构件类型,例如jar、war、ear、pom。插件可以创建他们自己的构件类型,所以前面列的不是全部构件类型 -->
<packaging> jar </packaging>
<!-- 项目当前版本,格式为:主版本.次版本.增量版本-限定版本号 -->
<version> 1.0-SNAPSHOT </version>
<!-- 项目的名称, Maven产生的文档用 -->
<name> xxx-maven </name>
<!-- 项目主页的URL, Maven产生的文档用 -->
<url> http://maven.apache.org </url>
<!-- 项目的详细描述, Maven 产生的文档用。 当这个元素能够用HTML格式描述时(例如,CDATA中的文本会被解析器忽略,
就可以包含HTML标签), 不鼓励使用纯文本描述。如果你需要修改产生的web站点的索引页面,你应该修改你自己的
索引页文件,而不是调整这里的文档。 -->
<description> A maven project to study maven. </description>
<!-- 描述了这个项目构建环境中的前提条件。 -->
<prerequisites>
<!-- 构建该项目或使用该插件所需要的Maven的最低版本 -->
<maven></maven>
</prerequisites>
<!-- 项目的问题管理系统(Bugzilla, Jira, Scarab,或任何你喜欢的问题管理系统)的名称和URL,本例为 jira -->
<issueManagement>
<!-- 问题管理系统(例如jira)的名字, -->
<system> jira </system>
<!-- 该项目使用的问题管理系统的URL -->
<url> http://jira.baidu.com/banseon </url>
</issueManagement>
<!-- 项目持续集成信息 -->
<ciManagement>
<!-- 持续集成系统的名字,例如continuum -->
<system></system>
<!-- 该项目使用的持续集成系统的URL(如果持续集成系统有web接口的话)。 -->
<url></url>
<!-- 构建完成时,需要通知的开发者/用户的配置项。包括被通知者信息和通知条件(错误,失败,成功,警告) -->
<notifiers>
<!-- 配置一种方式,当构建中断时,以该方式通知用户/开发者 -->
<notifier>
<!-- 传送通知的途径 -->
<type></type>
<!-- 发生错误时是否通知 -->
<sendOnError></sendOnError>
<!-- 构建失败时是否通知 -->
<sendOnFailure></sendOnFailure>
<!-- 构建成功时是否通知 -->
<sendOnSuccess></sendOnSuccess>
<!-- 发生警告时是否通知 -->
<sendOnWarning></sendOnWarning>
<!-- 不赞成使用。通知发送到哪里 -->
<address></address>
<!-- 扩展配置项 -->
<configuration></configuration>
</notifier>
</notifiers>
</ciManagement>
<!-- 项目创建年份,4位数字。当产生版权信息时需要使用这个值。 -->
<inceptionYear />
<!-- 项目相关邮件列表信息 -->
<mailingLists>
<!-- 该元素描述了项目相关的所有邮件列表。自动产生的网站引用这些信息。 -->
<mailingList>
<!-- 邮件的名称 -->
<name> Demo </name>
<!-- 发送邮件的地址或链接,如果是邮件地址,创建文档时,mailto: 链接会被自动创建 -->
<post> banseon@126.com </post>
<!-- 订阅邮件的地址或链接,如果是邮件地址,创建文档时,mailto: 链接会被自动创建 -->
<subscribe> banseon@126.com </subscribe>
<!-- 取消订阅邮件的地址或链接,如果是邮件地址,创建文档时,mailto: 链接会被自动创建 -->
<unsubscribe> banseon@126.com </unsubscribe>
<!-- 你可以浏览邮件信息的URL -->
<archive> http:/hi.baidu.com/banseon/demo/dev/ </archive>
</mailingList>
</mailingLists>
<!-- 项目开发者列表 -->
<developers>
<!-- 某个项目开发者的信息 -->
<developer>
<!-- SCM里项目开发者的唯一标识符 -->
<id> HELLO WORLD </id>
<!-- 项目开发者的全名 -->
<name> banseon </name>
<!-- 项目开发者的email -->
<email> banseon@126.com </email>
<!-- 项目开发者的主页的URL -->
<url></url>
<!-- 项目开发者在项目中扮演的角色,角色元素描述了各种角色 -->
<roles>
<role> Project Manager </role>
<role> Architect </role>
</roles>
<!-- 项目开发者所属组织 -->
<organization> demo </organization>
<!-- 项目开发者所属组织的URL -->
<organizationUrl> http://hi.baidu.com/xxx </organizationUrl>
<!-- 项目开发者属性,如即时消息如何处理等 -->
<properties>
<dept> No </dept>
</properties>
<!-- 项目开发者所在时区, -11到12范围内的整数。 -->
<timezone> -5 </timezone>
</developer>
</developers>
<!-- 项目的其他贡献者列表 -->
<contributors>
<!-- 项目的其他贡献者。参见developers/developer元素 -->
<contributor>
<!-- 项目贡献者的全名 -->
<name></name>
<!-- 项目贡献者的email -->
<email></email>
<!-- 项目贡献者的主页的URL -->
<url></url>
<!-- 项目贡献者所属组织 -->
<organization></organization>
<!-- 项目贡献者所属组织的URL -->
<organizationUrl></organizationUrl>
<!-- 项目贡献者在项目中扮演的角色,角色元素描述了各种角色 -->
<roles>
<role> Project Manager </role>
<role> Architect </role>
</roles>
<!-- 项目贡献者所在时区, -11到12范围内的整数。 -->
<timezone></timezone>
<!-- 项目贡献者属性,如即时消息如何处理等 -->
<properties>
<dept> No </dept>
</properties>
</contributor>
</contributors>
<!-- 该元素描述了项目所有License列表。 应该只列出该项目的license列表,不要列出依赖项目的 license列表。
如果列出多个license,用户可以选择它们中的一个而不是接受所有license。 -->
<licenses>
<!-- 描述了项目的license,用于生成项目的web站点的license页面,其他一些报表和validation也会用到该元素。 -->
<license>
<!-- license用于法律上的名称 -->
<name> Apache 2 </name>
<!-- 官方的license正文页面的URL -->
<url> http://www.baidu.com/banseon/LICENSE-2.0.txt </url>
<!-- 项目分发的主要方式:
repo,可以从Maven库下载
manual, 用户必须手动下载和安装依赖 -->
<distribution> repo </distribution>
<!-- 关于license的补充信息 -->
<comments> A business-friendly OSS license </comments>
</license>
</licenses>
<!-- SCM(Source Control Management)标签允许你配置你的代码库,供Maven web站点和其它插件使用。 -->
<scm>
<!-- SCM的URL,该URL描述了版本库和如何连接到版本库。欲知详情,请看SCMs提供的URL格式和列表。该连接只读。 -->
<connection>
scm:svn:http://svn.baidu.com/banseon/maven/banseon/banseon-maven2-trunk(dao-trunk)
</connection>
<!-- 给开发者使用的,类似connection元素。即该连接不仅仅只读 -->
<developerConnection>
scm:svn:http://svn.baidu.com/banseon/maven/banseon/dao-trunk
</developerConnection>
<!-- 当前代码的标签,在开发阶段默认为HEAD -->
<tag></tag>
<!-- 指向项目的可浏览SCM库(例如ViewVC或者Fisheye)的URL。 -->
<url> http://svn.baidu.com/banseon </url>
</scm>
<!-- 描述项目所属组织的各种属性。Maven产生的文档用 -->
<organization>
<!-- 组织的全名 -->
<name> demo </name>
<!-- 组织主页的URL -->
<url> http://www.baidu.com/banseon </url>
</organization>
<!-- 构建项目需要的信息 -->
<build>
<!-- 该元素设置了项目源码目录,当构建项目的时候,构建系统会编译目录里的源码。该路径是相对
于pom.xml的相对路径。 -->
<sourceDirectory></sourceDirectory>
<!-- 该元素设置了项目脚本源码目录,该目录和源码目录不同:绝大多数情况下,该目录下的内容会
被拷贝到输出目录(因为脚本是被解释的,而不是被编译的)。 -->
<scriptSourceDirectory></scriptSourceDirectory>
<!-- 该元素设置了项目单元测试使用的源码目录,当测试项目的时候,构建系统会编译目录里的源码。
该路径是相对于pom.xml的相对路径。 -->
<testSourceDirectory></testSourceDirectory>
<!-- 被编译过的应用程序class文件存放的目录。 -->
<outputDirectory></outputDirectory>
<!-- 被编译过的测试class文件存放的目录。 -->
<testOutputDirectory></testOutputDirectory>
<!-- 使用来自该项目的一系列构建扩展 -->
<extensions>
<!-- 描述使用到的构建扩展。 -->
<extension>
<!-- 构建扩展的groupId -->
<groupId></groupId>
<!-- 构建扩展的artifactId -->
<artifactId></artifactId>
<!-- 构建扩展的版本 -->
<version></version>
</extension>
</extensions>
<!-- 当项目没有规定目标(Maven2 叫做阶段)时的默认值 -->
<defaultGoal></defaultGoal>
<!-- 这个元素描述了项目相关的所有资源路径列表,例如和项目相关的属性文件,这些资源被包含在
最终的打包文件里。 -->
<resources>
<!-- 这个元素描述了项目相关或测试相关的所有资源路径 -->
<resource>
<!-- 描述了资源的目标路径。该路径相对target/classes目录(例如${project.build.outputDirectory})。
举个例子,如果你想资源在特定的包里(org.apache.maven.messages),你就必须该元素设置为
org/apache/maven/messages。然而,如果你只是想把资源放到源码目录结构里,就不需要该配置。 -->
<targetPath></targetPath>
<!-- 是否使用参数值代替参数名。参数值取自properties元素或者文件里配置的属性,文件在filters元素
里列出。 -->
<filtering></filtering>
<!-- 描述存放资源的目录,该路径相对POM路径 -->
<directory></directory>
<!-- 包含的模式列表,例如**/*.xml. -->
<includes>
<include></include>
</includes>
<!-- 排除的模式列表,例如**/*.xml -->
<excludes>
<exclude></exclude>
</excludes>
</resource>
</resources>
<!-- 这个元素描述了单元测试相关的所有资源路径,例如和单元测试相关的属性文件。 -->
<testResources>
<!-- 这个元素描述了测试相关的所有资源路径,参见build/resources/resource元素的说明 -->
<testResource>
<!-- 描述了测试相关的资源的目标路径。该路径相对target/classes目录(例如${project.build.outputDirectory})。
举个例子,如果你想资源在特定的包里(org.apache.maven.messages),你就必须该元素设置为
org/apache/maven/messages。然而,如果你只是想把资源放到源码目录结构里,就不需要该配置。 -->
<targetPath></targetPath>
<!-- 是否使用参数值代替参数名。参数值取自properties元素或者文件里配置的属性,文件在filters元素
里列出。 -->
<filtering></filtering>
<!-- 描述存放测试相关的资源的目录,该路径相对POM路径 -->
<directory></directory>
<!-- 包含的模式列表,例如**/*.xml. -->
<includes>
<include></include>
</includes>
<!-- 排除的模式列表,例如**/*.xml -->
<excludes>
<exclude></exclude>
</excludes>
</testResource>
</testResources>
<!-- 构建产生的所有文件存放的目录 -->
<directory></directory>
<!-- 产生的构件的文件名,默认值是${artifactId}-${version}。 -->
<finalName></finalName>
<!-- 当filtering开关打开时,使用到的过滤器属性文件列表 -->
<filters></filters>
<!-- 子项目可以引用的默认插件信息。该插件配置项直到被引用时才会被解析或绑定到生命周期。给定插件的任何本
地配置都会覆盖这里的配置 -->
<pluginManagement>
<!-- 使用的插件列表 。 -->
<plugins>
<!-- plugin元素包含描述插件所需要的信息。 -->
<plugin>
<!-- 插件在仓库里的group ID -->
<groupId></groupId>
<!-- 插件在仓库里的artifact ID -->
<artifactId></artifactId>
<!-- 被使用的插件的版本(或版本范围) -->
<version></version>
<!-- 是否从该插件下载Maven扩展(例如打包和类型处理器),由于性能原因,只有在真需要下载时,该
元素才被设置成enabled。 -->
<extensions>true/false</extensions>
<!-- 在构建生命周期中执行一组目标的配置。每个目标可能有不同的配置。 -->
<executions>
<!-- execution元素包含了插件执行需要的信息 -->
<execution>
<!-- 执行目标的标识符,用于标识构建过程中的目标,或者匹配继承过程中需要合并的执行目标 -->
<id></id>
<!-- 绑定了目标的构建生命周期阶段,如果省略,目标会被绑定到源数据里配置的默认阶段 -->
<phase></phase>
<!-- 配置的执行目标 -->
<goals></goals>
<!-- 配置是否被传播到子POM -->
<inherited>true/false</inherited>
<!-- 作为DOM对象的配置 -->
<configuration></configuration>
</execution>
</executions>
<!-- 项目引入插件所需要的额外依赖 -->
<dependencies>
<!-- 参见dependencies/dependency元素 -->
<dependency>
</dependency>
</dependencies>
<!-- 任何配置是否被传播到子项目 -->
<inherited>true/false</inherited>
<!-- 作为DOM对象的配置 -->
<configuration></configuration>
</plugin>
</plugins>
</pluginManagement>
<!-- 该项目使用的插件列表 。 -->
<plugins>
<!-- plugin元素包含描述插件所需要的信息。 -->
<plugin>
<!-- 插件在仓库里的group ID -->
<groupId></groupId>
<!-- 插件在仓库里的artifact ID -->
<artifactId></artifactId>
<!-- 被使用的插件的版本(或版本范围) -->
<version></version>
<!-- 是否从该插件下载Maven扩展(例如打包和类型处理器),由于性能原因,只有在真需要下载时,该
元素才被设置成enabled。 -->
<extensions>true/false</extensions>
<!-- 在构建生命周期中执行一组目标的配置。每个目标可能有不同的配置。 -->
<executions>
<!-- execution元素包含了插件执行需要的信息 -->
<execution>
<!-- 执行目标的标识符,用于标识构建过程中的目标,或者匹配继承过程中需要合并的执行目标 -->
<id></id>
<!-- 绑定了目标的构建生命周期阶段,如果省略,目标会被绑定到源数据里配置的默认阶段 -->
<phase></phase>
<!-- 配置的执行目标 -->
<goals></goals>
<!-- 配置是否被传播到子POM -->
<inherited>true/false</inherited>
<!-- 作为DOM对象的配置 -->
<configuration></configuration>
</execution>
</executions>
<!-- 项目引入插件所需要的额外依赖 -->
<dependencies>
<!-- 参见dependencies/dependency元素 -->
<dependency>
</dependency>
</dependencies>
<!-- 任何配置是否被传播到子项目 -->
<inherited>true/false</inherited>
<!-- 作为DOM对象的配置 -->
<configuration></configuration>
</plugin>
</plugins>
</build>
<!-- 在列的项目构建profile,如果被激活,会修改构建处理 -->
<profiles>
<!-- 根据环境参数或命令行参数激活某个构建处理 -->
<profile>
<!-- 构建配置的唯一标识符。即用于命令行激活,也用于在继承时合并具有相同标识符的profile。 -->
<id></id>
<!-- 自动触发profile的条件逻辑。Activation是profile的开启钥匙。profile的力量来自于它能够
在某些特定的环境中自动使用某些特定的值;这些环境通过activation元素指定。activation元
素并不是激活profile的唯一方式。 -->
<activation>
<!-- profile默认是否激活的标志 -->
<activeByDefault>true/false</activeByDefault>
<!-- 当匹配的jdk被检测到,profile被激活。例如,1.4激活JDK1.4,1.4.0_2,而!1.4激活所有版本
不是以1.4开头的JDK。 -->
<jdk>jdk版本,如:1.7</jdk>
<!-- 当匹配的操作系统属性被检测到,profile被激活。os元素可以定义一些操作系统相关的属性。 -->
<os>
<!-- 激活profile的操作系统的名字 -->
<name> Windows XP </name>
<!-- 激活profile的操作系统所属家族(如 'windows') -->
<family> Windows </family>
<!-- 激活profile的操作系统体系结构 -->
<arch> x86 </arch>
<!-- 激活profile的操作系统版本 -->
<version> 5.1.2600 </version>
</os>
<!-- 如果Maven检测到某一个属性(其值可以在POM中通过${名称}引用),其拥有对应的名称和值,Profile
就会被激活。如果值字段是空的,那么存在属性名称字段就会激活profile,否则按区分大小写方式匹
配属性值字段 -->
<property>
<!-- 激活profile的属性的名称 -->
<name> mavenVersion </name>
<!-- 激活profile的属性的值 -->
<value> 2.0.3 </value>
</property>
<!-- 提供一个文件名,通过检测该文件的存在或不存在来激活profile。missing检查文件是否存在,如果不存在则激活
profile。另一方面,exists则会检查文件是否存在,如果存在则激活profile。 -->
<file>
<!-- 如果指定的文件存在,则激活profile。 -->
<exists> /usr/local/hudson/hudson-home/jobs/maven-guide-zh-to-production/workspace/ </exists>
<!-- 如果指定的文件不存在,则激活profile。 -->
<missing> /usr/local/hudson/hudson-home/jobs/maven-guide-zh-to-production/workspace/ </missing>
</file>
</activation>
<!-- 构建项目所需要的信息。参见build元素 -->
<build>
<defaultGoal />
<resources>
<resource>
<targetPath></targetPath>
<filtering></filtering>
<directory></directory>
<includes>
<include></include>
</includes>
<excludes>
<exclude></exclude>
</excludes>
</resource>
</resources>
<testResources>
<testResource>
<targetPath></targetPath>
<filtering></filtering>
<directory></directory>
<includes>
<include></include>
</includes>
<excludes>
<exclude></exclude>
</excludes>
</testResource>
</testResources>
<directory></directory>
<finalName></finalName>
<filters></filters>
<pluginManagement>
<plugins>
<!-- 参见build/pluginManagement/plugins/plugin元素 -->
<plugin>
<groupId></groupId>
<artifactId></artifactId>
<version></version>
<extensions>true/false</extensions>
<executions>
<execution>
<id></id>
<phase></phase>
<goals></goals>
<inherited>true/false</inherited>
<configuration></configuration>
</execution>
</executions>
<dependencies>
<!-- 参见dependencies/dependency元素 -->
<dependency>
</dependency>
</dependencies>
<goals></goals>
<inherited>true/false</inherited>
<configuration></configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<!-- 参见build/pluginManagement/plugins/plugin元素 -->
<plugin>
<groupId></groupId>
<artifactId></artifactId>
<version></version>
<extensions>true/false</extensions>
<executions>
<execution>
<id></id>
<phase></phase>
<goals></goals>
<inherited>true/false</inherited>
<configuration></configuration>
</execution>
</executions>
<dependencies>
<!-- 参见dependencies/dependency元素 -->
<dependency>
</dependency>
</dependencies>
<goals></goals>
<inherited>true/false</inherited>
<configuration></configuration>
</plugin>
</plugins>
</build>
<!-- 模块(有时称作子项目) 被构建成项目的一部分。列出的每个模块元素是指向该模块的目录的
相对路径 -->
<modules>
<!--子项目相对路径-->
<module></module>
</modules>
<!-- 发现依赖和扩展的远程仓库列表。 -->
<repositories>
<!-- 参见repositories/repository元素 -->
<repository>
<releases>
<enabled><enabled>
<updatePolicy></updatePolicy>
<checksumPolicy></checksumPolicy>
</releases>
<snapshots>
<enabled><enabled>
<updatePolicy></updatePolicy>
<checksumPolicy></checksumPolicy>
</snapshots>
<id></id>
<name></name>
<url></url>
<layout></layout>
</repository>
</repositories>
<!-- 发现插件的远程仓库列表,这些插件用于构建和报表 -->
<pluginRepositories>
<!-- 包含需要连接到远程插件仓库的信息.参见repositories/repository元素 -->
<pluginRepository>
<releases>
<enabled><enabled>
<updatePolicy></updatePolicy>
<checksumPolicy></checksumPolicy>
</releases>
<snapshots>
<enabled><enabled>
<updatePolicy></updatePolicy>
<checksumPolicy></checksumPolicy>
</snapshots>
<id></id>
<name></name>
<url></url>
<layout></layout>
</pluginRepository>
</pluginRepositories>
<!-- 该元素描述了项目相关的所有依赖。 这些依赖组成了项目构建过程中的一个个环节。它们自动从项目定义的
仓库中下载。要获取更多信息,请看项目依赖机制。 -->
<dependencies>
<!-- 参见dependencies/dependency元素 -->
<dependency>
</dependency>
</dependencies>
<!-- 不赞成使用. 现在Maven忽略该元素. -->
<reports></reports>
<!-- 该元素包括使用报表插件产生报表的规范。当用户执行“mvn site”,这些报表就会运行。 在页面导航栏能看
到所有报表的链接。参见reporting元素 -->
<reporting></reporting>
<!-- 参见dependencyManagement元素 -->
<dependencyManagement>
<dependencies>
<!-- 参见dependencies/dependency元素 -->
<dependency>
</dependency>
</dependencies>
</dependencyManagement>
<!-- 参见distributionManagement元素 -->
<distributionManagement>
</distributionManagement>
<!-- 参见properties元素 -->
<properties />
</profile>
</profiles>
<!-- 模块(有时称作子项目) 被构建成项目的一部分。列出的每个模块元素是指向该模块的目录的相对路径 -->
<modules>
<!--子项目相对路径-->
<module></module>
</modules>
<!-- 发现依赖和扩展的远程仓库列表。 -->
<repositories>
<!-- 包含需要连接到远程仓库的信息 -->
<repository>
<!-- 如何处理远程仓库里发布版本的下载 -->
<releases>
<!-- true或者false表示该仓库是否为下载某种类型构件(发布版,快照版)开启。 -->
<enabled><enabled>
<!-- 该元素指定更新发生的频率。Maven会比较本地POM和远程POM的时间戳。这里的选项是:always(一直),
daily(默认,每日),interval:X(这里X是以分钟为单位的时间间隔),或者never(从不)。 -->
<updatePolicy></updatePolicy>
<!-- 当Maven验证构件校验文件失败时该怎么做:ignore(忽略),fail(失败),或者warn(警告)。 -->
<checksumPolicy></checksumPolicy>
</releases>
<!-- 如何处理远程仓库里快照版本的下载。有了releases和snapshots这两组配置,POM就可以在每个单独的仓库中,
为每种类型的构件采取不同的策略。例如,可能有人会决定只为开发目的开启对快照版本下载的支持。参见repositories/repository/releases元素 -->
<snapshots>
<enabled><enabled>
<updatePolicy></updatePolicy>
<checksumPolicy></checksumPolicy>
</snapshots>
<!-- 远程仓库唯一标识符。可以用来匹配在settings.xml文件里配置的远程仓库 -->
<id> banseon-repository-proxy </id>
<!-- 远程仓库名称 -->
<name> banseon-repository-proxy </name>
<!-- 远程仓库URL,按protocol://hostname/path形式 -->
<url> http://192.168.1.169:9999/repository/ </url>
<!-- 用于定位和排序构件的仓库布局类型-可以是default(默认)或者legacy(遗留)。Maven 2为其仓库提供了一个默认
的布局;然而,Maven 1.x有一种不同的布局。我们可以使用该元素指定布局是default(默认)还是legacy(遗留)。 -->
<layout> default </layout>
</repository>
</repositories>
<!-- 发现插件的远程仓库列表,这些插件用于构建和报表 -->
<pluginRepositories>
<!-- 包含需要连接到远程插件仓库的信息.参见repositories/repository元素 -->
<pluginRepository>
</pluginRepository>
</pluginRepositories>
<!-- 该元素描述了项目相关的所有依赖。 这些依赖组成了项目构建过程中的一个个环节。它们自动从项目定义的仓库中下载。
要获取更多信息,请看项目依赖机制。 -->
<dependencies>
<dependency>
<!-- 依赖的group ID -->
<groupId> org.apache.maven </groupId>
<!-- 依赖的artifact ID -->
<artifactId> maven-artifact </artifactId>
<!-- 依赖的版本号。 在Maven 2里, 也可以配置成版本号的范围。 -->
<version> 3.8.1 </version>
<!-- 依赖类型,默认类型是jar。它通常表示依赖的文件的扩展名,但也有例外。一个类型可以被映射成另外一个扩展
名或分类器。类型经常和使用的打包方式对应,尽管这也有例外。一些类型的例子:jar,war,ejb-client和test-jar。
如果设置extensions为 true,就可以在plugin里定义新的类型。所以前面的类型的例子不完整。 -->
<type> jar </type>
<!-- 依赖的分类器。分类器可以区分属于同一个POM,但不同构建方式的构件。分类器名被附加到文件名的版本号后面。例如,
如果你想要构建两个单独的构件成JAR,一个使用Java 1.4编译器,另一个使用Java 6编译器,你就可以使用分类器来生
成两个单独的JAR构件。 -->
<classifier></classifier>
<!-- 依赖范围。在项目发布过程中,帮助决定哪些构件被包括进来。欲知详情请参考依赖机制。
- compile :默认范围,用于编译
- provided:类似于编译,但支持你期待jdk或者容器提供,类似于classpath
- runtime: 在执行时需要使用
- test: 用于test任务时使用
- system: 需要外在提供相应的元素。通过systemPath来取得
- systemPath: 仅用于范围为system。提供相应的路径
- optional: 当项目自身被依赖时,标注依赖是否传递。用于连续依赖时使用 -->
<scope> test </scope>
<!-- 仅供system范围使用。注意,不鼓励使用这个元素,并且在新的版本中该元素可能被覆盖掉。该元素为依赖规定了文件
系统上的路径。需要绝对路径而不是相对路径。推荐使用属性匹配绝对路径,例如${java.home}。 -->
<systemPath></systemPath>
<!-- 当计算传递依赖时, 从依赖构件列表里,列出被排除的依赖构件集。即告诉maven你只依赖指定的项目,不依赖项目的
依赖。此元素主要用于解决版本冲突问题 -->
<exclusions>
<exclusion>
<artifactId> spring-core </artifactId>
<groupId> org.springframework </groupId>
</exclusion>
</exclusions>
<!-- 可选依赖,如果你在项目B中把C依赖声明为可选,你就需要在依赖于B的项目(例如项目A)中显式的引用对C的依赖。
可选依赖阻断依赖的传递性。 -->
<optional> true </optional>
</dependency>
</dependencies>
<!-- 不赞成使用. 现在Maven忽略该元素. -->
<reports></reports>
<!-- 该元素描述使用报表插件产生报表的规范。当用户执行“mvn site”,这些报表就会运行。 在页面导航栏能看到所有报表的链接。 -->
<reporting>
<!-- true,则,网站不包括默认的报表。这包括“项目信息”菜单中的报表。 -->
<excludeDefaults />
<!-- 所有产生的报表存放到哪里。默认值是${project.build.directory}/site。 -->
<outputDirectory />
<!-- 使用的报表插件和他们的配置。 -->
<plugins>
<!-- plugin元素包含描述报表插件需要的信息 -->
<plugin>
<!-- 报表插件在仓库里的group ID -->
<groupId></groupId>
<!-- 报表插件在仓库里的artifact ID -->
<artifactId></artifactId>
<!-- 被使用的报表插件的版本(或版本范围) -->
<version></version>
<!-- 任何配置是否被传播到子项目 -->
<inherited>true/false</inherited>
<!-- 报表插件的配置 -->
<configuration></configuration>
<!-- 一组报表的多重规范,每个规范可能有不同的配置。一个规范(报表集)对应一个执行目标 。例如,
有1,2,3,4,5,6,7,8,9个报表。1,2,5构成A报表集,对应一个执行目标。2,5,8构成B报
表集,对应另一个执行目标 -->
<reportSets>
<!-- 表示报表的一个集合,以及产生该集合的配置 -->
<reportSet>
<!-- 报表集合的唯一标识符,POM继承时用到 -->
<id></id>
<!-- 产生报表集合时,被使用的报表的配置 -->
<configuration></configuration>
<!-- 配置是否被继承到子POMs -->
<inherited>true/false</inherited>
<!-- 这个集合里使用到哪些报表 -->
<reports></reports>
</reportSet>
</reportSets>
</plugin>
</plugins>
</reporting>
<!-- 继承自该项目的所有子项目的默认依赖信息。这部分的依赖信息不会被立即解析,而是当子项目声明一个依赖
(必须描述group ID和artifact ID信息),如果group ID和artifact ID以外的一些信息没有描述,则通过
group ID和artifact ID匹配到这里的依赖,并使用这里的依赖信息。 -->
<dependencyManagement>
<dependencies>
<!-- 参见dependencies/dependency元素 -->
<dependency>
</dependency>
</dependencies>
</dependencyManagement>
<!-- 项目分发信息,在执行mvn deploy后表示要发布的位置。有了这些信息就可以把网站部署到远程服务器或者
把构件部署到远程仓库。 -->
<distributionManagement>
<!-- 部署项目产生的构件到远程仓库需要的信息 -->
<repository>
<!-- 是分配给快照一个唯一的版本号(由时间戳和构建流水号)?还是每次都使用相同的版本号?参见
repositories/repository元素 -->
<uniqueVersion />
<id> banseon-maven2 </id>
<name> banseon maven2 </name>
<url> file://${basedir}/target/deploy </url>
<layout></layout>
</repository>
<!-- 构件的快照部署到哪里?如果没有配置该元素,默认部署到repository元素配置的仓库,参见
distributionManagement/repository元素 -->
<snapshotRepository>
<uniqueVersion />
<id> banseon-maven2 </id>
<name> Banseon-maven2 Snapshot Repository </name>
<url> scp://svn.baidu.com/banseon:/usr/local/maven-snapshot </url>
<layout></layout>
</snapshotRepository>
<!-- 部署项目的网站需要的信息 -->
<site>
<!-- 部署位置的唯一标识符,用来匹配站点和settings.xml文件里的配置 -->
<id> banseon-site </id>
<!-- 部署位置的名称 -->
<name> business api website </name>
<!-- 部署位置的URL,按protocol://hostname/path形式 -->
<url>
scp://svn.baidu.com/banseon:/var/www/localhost/banseon-web
</url>
</site>
<!-- 项目下载页面的URL。如果没有该元素,用户应该参考主页。使用该元素的原因是:帮助定位
那些不在仓库里的构件(由于license限制)。 -->
<downloadUrl />
<!-- 如果构件有了新的group ID和artifact ID(构件移到了新的位置),这里列出构件的重定位信息。 -->
<relocation>
<!-- 构件新的group ID -->
<groupId></groupId>
<!-- 构件新的artifact ID -->
<artifactId></artifactId>
<!-- 构件新的版本号 -->
<version></version>
<!-- 显示给用户的,关于移动的额外信息,例如原因。 -->
<message></message>
</relocation>
<!-- 给出该构件在远程仓库的状态。不得在本地项目中设置该元素,因为这是工具自动更新的。有效的值
有:none(默认),converted(仓库管理员从Maven 1 POM转换过来),partner(直接从伙伴Maven
2仓库同步过来),deployed(从Maven 2实例部署),verified(被核实时正确的和最终的)。 -->
<status></status>
</distributionManagement>
<!-- 以值替代名称,Properties可以在整个POM中使用,也可以作为触发条件(见settings.xml配置文件里
activation元素的说明)。格式是<name>value</name>。 -->
<properties>
<name>value</name>
</properties>
</project>
附件2:POM文件单项配置说明
localRepository
<!-- 本地仓库的路径。默认值为${user.home}/.m2/repository。 -->
<localRepository>usr/local/maven</localRepository>
interactiveMode
<!--Maven是否需要和用户交互以获得输入。如果Maven需要和用户交互以获得输入,则设置成true,反之则应为false。默认为true。-->
<interactiveMode>true</interactiveMode>
usePluginRegistry
<!--Maven是否需要使用plugin-registry.xml文件来管理插件版本。如果需要让Maven使用文件${user.home}/.m2/plugin-registry.xml来管理插件版本,则设为true。默认为false。-->
<usePluginRegistry>false</usePluginRegistry>
offline
<!--表示Maven是否需要在离线模式下运行。如果构建系统需要在离线模式下运行,则为true,默认为false。当由于网络设置原因或者安全因素,构建服务器不能连接远程仓库的时候,该配置就十分有用。 -->
<offline>false</offline>
pluginGroups
<!--当插件的组织Id(groupId)没有显式提供时,供搜寻插件组织Id(groupId)的列表。该元素包含一个pluginGroup元素列表,每个子元素包含了一个组织Id(groupId)。当我们使用某个插件,并且没有在命令行为其提供组织Id(groupId)的时候,Maven就会使用该列表。默认情况下该列表包含了org.apache.maven.plugins和org.codehaus.mojo -->
<pluginGroups>
<!--plugin的组织Id(groupId) -->
<pluginGroup>org.codehaus.mojo</pluginGroup>
</pluginGroups>
proxies
<!--用来配置不同的代理,多代理profiles 可以应对笔记本或移动设备的工作环境:通过简单的设置profile id就可以很容易的更换整个代理配置。 -->
<proxies>
<!--代理元素包含配置代理时需要的信息-->
<proxy>
<!--代理的唯一定义符,用来区分不同的代理元素。-->
<id>myproxy</id>
<!--该代理是否是激活的那个。true则激活代理。当我们声明了一组代理,而某个时候只需要激活一个代理的时候,该元素就可以派上用处。 -->
<active>true</active>
<!--代理的协议。 协议://主机名:端口,分隔成离散的元素以方便配置。-->
<protocol>http</protocol>
<!--代理的主机名。协议://主机名:端口,分隔成离散的元素以方便配置。 -->
<host>proxy.somewhere.com</host>
<!--代理的端口。协议://主机名:端口,分隔成离散的元素以方便配置。 -->
<port>8080</port>
<!--代理的用户名,用户名和密码表示代理服务器认证的登录名和密码。 -->
<username>proxyuser</username>
<!--代理的密码,用户名和密码表示代理服务器认证的登录名和密码。 -->
<password>somepassword</password>
<!--不该被代理的主机名列表。该列表的分隔符由代理服务器指定;例子中使用了竖线分隔符,使用逗号分隔也很常见。-->
<nonProxyHosts>*.google.com|ibiblio.org</nonProxyHosts>
</proxy>
</proxies>
servers
<!--配置服务端的一些设置。一些设置如安全证书不应该和pom.xml一起分发。这种类型的信息应该存在于构建服务器上的settings.xml文件中。-->
<servers>
<!--服务器元素包含配置服务器时需要的信息 -->
<server>
<!--这是server的id(注意不是用户登陆的id),该id与distributionManagement中repository元素的id相匹配。-->
<id>server001</id>
<!--鉴权用户名。鉴权用户名和鉴权密码表示服务器认证所需要的登录名和密码。 -->
<username>my_login</username>
<!--鉴权密码 。鉴权用户名和鉴权密码表示服务器认证所需要的登录名和密码。密码加密功能已被添加到2.1.0 +。详情请访问密码加密页面-->
<password>my_password</password>
<!--鉴权时使用的私钥位置。和前两个元素类似,私钥位置和私钥密码指定了一个私钥的路径(默认是${user.home}/.ssh/id_dsa)以及如果需要的话,一个密语。将来passphrase和password元素可能会被提取到外部,但目前它们必须在settings.xml文件以纯文本的形式声明。 -->
<privateKey>${usr.home}/.ssh/id_dsa</privateKey>
<!--鉴权时使用的私钥密码。-->
<passphrase>some_passphrase</passphrase>
<!--文件被创建时的权限。如果在部署的时候会创建一个仓库文件或者目录,这时候就可以使用权限(permission)。这两个元素合法的值是一个三位数字,其对应了unix文件系统的权限,如664,或者775。 -->
<filePermissions>664</filePermissions>
<!--目录被创建时的权限。 -->
<directoryPermissions>775</directoryPermissions>
</server>
</servers>
mirrors
<!--为仓库列表配置的下载镜像列表。高级设置请参阅镜像设置页面 -->
<mirrors>
<!--给定仓库的下载镜像。 -->
<mirror>
<!--该镜像的唯一标识符。id用来区分不同的mirror元素。 -->
<id>planetmirror.com</id>
<!--镜像名称 -->
<name>PlanetMirror Australia</name>
<!--该镜像的URL。构建系统会优先考虑使用该URL,而非使用默认的服务器URL。 -->
<url>http://downloads.planetmirror.com/pub/maven2</url>
<!--被镜像的服务器的id。例如,如果我们要设置了一个Maven中央仓库(http://repo.maven.apache.org/maven2/)的镜像,就需要将该元素设置成central。这必须和中央仓库的id central完全一致。-->
<mirrorOf>central</mirrorOf>
</mirror>
</mirrors>
profiles
<!--根据环境参数来调整构建配置的列表。settings.xml中的profile元素是pom.xml中profile元素的裁剪版本。它包含了id,activation, repositories, pluginRepositories和 properties元素。这里的profile元素只包含这五个子元素是因为这里只关心构建系统这个整体(这正是settings.xml文件的角色定位),而非单独的项目对象模型设置。如果一个settings中的profile被激活,它的值会覆盖任何其它定义在POM中或者profile.xml中的带有相同id的profile。 -->
<profiles>
<!--根据环境参数来调整的构件的配置-->
<profile>
<!--该配置的唯一标识符。 -->
<id>test</id>
Activation
<!--自动触发profile的条件逻辑。Activation是profile的开启钥匙。如POM中的profile一样,profile的力量来自于它能够在某些特定的环境中自动使用某些特定的值;这些环境通过activation元素指定。activation元素并不是激活profile的唯一方式。settings.xml文件中的activeProfile元素可以包含profile的id。profile也可以通过在命令行,使用-P标记和逗号分隔的列表来显式的激活(如,-P test)。-->
<activation>
<!--profile默认是否激活的标识-->
<activeByDefault>false</activeByDefault>
<!--当匹配的jdk被检测到,profile被激活。例如,1.4激活JDK1.4,1.4.0_2,而!1.4激活所有版本不是以1.4开头的JDK。-->
<jdk>1.5</jdk>
<!--当匹配的操作系统属性被检测到,profile被激活。os元素可以定义一些操作系统相关的属性。-->
<os>
<!--激活profile的操作系统的名字 -->
<name>Windows XP</name>
<!--激活profile的操作系统所属家族(如 'windows') -->
<family>Windows</family>
<!--激活profile的操作系统体系结构 -->
<arch>x86</arch>
<!--激活profile的操作系统版本-->
<version>5.1.2600</version>
</os>
<!--如果Maven检测到某一个属性(其值可以在POM中通过${name}引用),其拥有对应的name = 值,Profile就会被激活。如果值字段是空的,那么存在属性名称字段就会激活profile,否则按区分大小写方式匹配属性值字段-->
<property>
<!--激活profile的属性的名称-->
<name>mavenVersion</name>
<!--激活profile的属性的值 -->
<value>2.0.3</value>
</property>
<!--提供一个文件名,通过检测该文件的存在或不存在来激活profile。missing检查文件是否存在,如果不存在则激活profile。另一方面,exists则会检查文件是否存在,如果存在则激活profile。-->
<file>
<!--如果指定的文件存在,则激活profile。 -->
<exists>${basedir}/file2.properties</exists>
<!--如果指定的文件不存在,则激活profile。-->
<missing>${basedir}/file1.properties</missing>
</file>
</activation>
Repositories
<!--远程仓库列表,它是Maven用来填充构建系统本地仓库所使用的一组远程项目。 -->
<repositories>
<!--包含需要连接到远程仓库的信息 -->
<repository>
<!--远程仓库唯一标识-->
<id>codehausSnapshots</id>
<!--远程仓库名称 -->
<name>Codehaus Snapshots</name>
<!--如何处理远程仓库里发布版本的下载-->
<releases>
<!--true或者false表示该仓库是否为下载某种类型构件(发布版,快照版)开启。 -->
<enabled>false</enabled>
<!--该元素指定更新发生的频率。Maven会比较本地POM和远程POM的时间戳。这里的选项是:always(一直),daily(默认,每日),interval:X(这里X是以分钟为单位的时间间隔),或者never(从不)。 -->
<updatePolicy>always</updatePolicy>
<!--当Maven验证构件校验文件失败时该怎么做-ignore(忽略),fail(失败),或者warn(警告)。-->
<checksumPolicy>warn</checksumPolicy>
</releases>
<!--如何处理远程仓库里快照版本的下载。有了releases和snapshots这两组配置,POM就可以在每个单独的仓库中,为每种类型的构件采取不同的策略。例如,可能有人会决定只为开发目的开启对快照版本下载的支持。参见repositories/repository/releases元素-->
<snapshots>
<enabled/><updatePolicy/><checksumPolicy/>
</snapshots>
<!--远程仓库URL,按protocol://hostname/path形式 -->
<url>http://snapshots.maven.codehaus.org/maven2</url>
<!--用于定位和排序构件的仓库布局类型-可以是default(默认)或者legacy(遗留)。Maven 2为其仓库提供了一个默认的布局;然而,Maven 1.x有一种不同的布局。我们可以使用该元素指定布局是default(默认)还是legacy(遗留)。 -->
<layout>default</layout>
</repository>
</repositories>
<!--发现插件的远程仓库列表。仓库是两种主要构件的家。第一种构件被用作其它构件的依赖。这是中央仓库中存储的大部分构件类型。另外一种构件类型是插件。Maven插件是一种特殊类型的构件。由于这个原因,插件仓库独立于其它仓库。pluginRepositories元素的结构和repositories元素的结构类似。每个pluginRepository元素指定一个Maven可以用来寻找新插件的远程地址。-->
<pluginRepositories>
<!--包含需要连接到远程插件仓库的信息.参见profiles/profile/repositories/repository元素的说明-->
<pluginRepository>
<releases>
<enabled/><updatePolicy/><checksumPolicy/>
</releases>
<snapshots>
<enabled/><updatePolicy/><checksumPolicy/>
</snapshots>
<id/><name/><url/><layout/>
</pluginRepository>
</pluginRepositories>
</profile>
</profiles>
activeProfiles
<!--手动激活profiles的列表,按照profile被应用的顺序定义activeProfile。 该元素包含了一组activeProfile元素,每个activeProfile都含有一个profile id。任何在activeProfile中定义的profile id,不论环境设置如何,其对应的
profile都会被激活。如果没有匹配的profile,则什么都不会发生。例如,env-test是一个activeProfile,则在pom.xml(或者profile.xml)中对应id的profile会被激活。如果运行过程中找不到这样一个profile,Maven则会像往常一样运行。 -->
<activeProfiles>
<activeProfile>env-test</activeProfile>
</activeProfiles>
</settings>