关于Maven工程的复习(一)

来源:互联网 发布:云安全软件 编辑:程序博客网 时间:2024/05/16 10:14

一 关于pom.xml 的文件的详解

1 定义

pom:Project Object Model,项目对象模型。通过xml格式保存的pom.xml文件。作用类似ant的build.xml文件,功能更强大。该文件用于管理:源代码、配置文件、开发者的信息和角色、问题追踪系统、组织信息、项目授权、项目的url、项目的依赖关系等等。

2 关于官方的完整的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/maven-v4_0_0.xsd">        <modelVersion>4.0.0</modelVersion>        <!– The Basics –>        <groupId>…</groupId>        <artifactId>…</artifactId>        <version>…</version>        <packaging>…</packaging>        <dependencies>…</dependencies>        <parent>…</parent>        <dependencyManagement>…</dependencyManagement>        <modules>…</modules>        <properties>…</properties>        <!– Build Settings –>        <build>…</build>        <reporting>…</reporting>        <!– More Project Information –>        <name>…</name>        <description>…</description>        <url>…</url>        <inceptionYear>…</inceptionYear>        <licenses>…</licenses>        <organization>…</organization>        <developers>…</developers>        <contributors>…</contributors>        <!– Environment Settings –>        <issueManagement>…</issueManagement>        <ciManagement>…</ciManagement>        <mailingLists>…</mailingLists>        <scm>…</scm>        <prerequisites>…</prerequisites>        <repositories>…</repositories>        <pluginRepositories>…</pluginRepositories>        <distributionManagement>…</distributionManagement>        <profiles>…</profiles>      </project>  

3关于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/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>反写公司网址+项目名</groupId><artifactId>项目名+模块名</artifactId><version>0.0.1-SNAPSHOT</version><!--version中书写项目的版本号第一个0表示大版本号第二个0表示分支版本号第三个1表示小版本号snapshot快照版本alpha内测版beta公测版Release稳定版stable稳定版GA正式发布--><packaging></packaging><!--packaging打包方式默认是jar还有war,pom,zip,jar等方式--><name>项目的描述名</name><url>项目地址</url><description>项目描述</description><developers><developer>开发者<developer></developers><licenses>项目证书</licenses><orgranization>项目所属组织</orgranization><dependecies><dependency><groupId></groupId><artifactId></groupId><version></version><type></type><scope>依赖传递范围</scope><optional></optional><!--设置依赖是否可选,默认是false,子项目是继承的设置为true时,子项目不可以继承,子项目必须显示引入该依赖--><exclusions><exclusion><exclusion><exclusions><!--排除依赖,举例说明,A依赖B,B依赖C C对于A来说属于传递依赖如果A不想依赖C,就可以使用该标签--></dependency><dependencyManagement>依赖管理标签</dependencyManagement><pluginManagement>插件管理<pluginManagement><build><plugins><plugin><plugin></plugins></build><parent></parent><!--用于子模块或者工程继承父工程--><modules></modules><!--父工程包含哪些子模块--><settings><settings><!--定义属性,常用来定义依赖版本号--></dependecies></project>

4 <dependecyManagement> 的用途

在 父工程的版本控制 有一定的优势

1.作用:
maven使用dependencyManagement元素来提供了一种管理项目的所有依赖版本号的方式。一般
我们会在顶层的父项目中(集合工程的pom文件中)看到dependencyManagement的身影。
dependencyManagement可以让所有的子项目在引用一个依赖的时候不用列出具体的版本号。
maven会沿着父子关系向上走直到找到一个拥有 dependencyManagement元素的项目,
然后他就会使用在这个dependencyManagement定义的版本号。

2.好处:
多个子项目都引用同一个依赖,那么就可以避免在所有的子项目里面都声明一个依赖的版本号。
当你想升级或者切换到另一个版本的时候,只需要在顶层的父容器里的升级版本号即可;同时
当你的子项目需要特定的版本时只需要在子项目中声明一个version即可。

3.注意:

在dependencyManagement里面只是声明依赖,不实际引入依赖,因此在子项目里需要显示的声明
所要使用到的依赖。

**使用pluginManagement管理插件(优化插件管理)

作用:
maven使用pluginManagement元素来提供一种插件管理的方式。maven中的pluginManagement不会
造成插件的实际行为,只有当子模块中真正配置了plugin元素且其中groupid,artifactid与
pluginManagement中的相匹配的时候pluginManagement中的配置才会影响实际插件的行为。


5 <build>标签的使用

build中的主要标签:Resources和Plugins。

resources:用于排除或包含某些资源文件

    <resources>        <resource>          <targetPath>META-INF/plexus</targetPath>          <filtering>false</filtering>          <directory>${basedir}/src/main/plexus</directory>          <includes>            <include>configuration.xml</include>          </includes>          <excludes>            <exclude>**/*.properties</exclude>          </excludes>        </resource>      </resources>  
plugins:设置构建的插件
<build>     …     <plugins>       <plugin>         <groupId>org.apache.maven.plugins</groupId>         <artifactId>maven-jar-plugin</artifactId>         <version>2.0</version>         <extensions>false</extensions>         <inherited>true</inherited>         <configuration>           <classifier>test</classifier>         </configuration>         <dependencies>…</dependencies>         <executions>…</executions>       </plugin> 

6 关于继承关系和聚合关系的理解

 用一个现实的例子来表示这两者的关系

  继子 和  亲生儿子  在一个家庭中继子 和 亲生儿子在一起  聚合成了一个家庭 而相对于继子 并没有继承这个家族一些血缘关系 而亲生儿子继承了这个家族的血缘关系

聚合

我们在开发过程中,创建了2个以上的模块,每个模块都是一个独立的maven project,在开始的时候我们可以独立的编译和测试运行每个模块,但是随着项目的不断变大和复杂化,我们期望能够使用简单的操作来完成编译等工作,这时Maven给出了聚合的配置方式。

所谓聚合,顾名思义,就是把多个模块或项目聚合到一起,我们可以建立一个专门负责聚合工作的Maven 工程。

建立该project的时候,我们要注意以下几点:

1.聚合模块本身也做为一个Maven项目,它必须有自己的POM

2.它的打包方式必须为: pom

3.引入了新的元素:modules---module

4.版本:聚合模块的版本和被聚合模块版本一致

5.相对目录:每个module的值都是一个当前POM的相对目录

6.目录名称:为了方便的快速定位内容,模块所处的目录应当与其artifactId一致(Maven约定而不是硬性要求),总之,模块所处的目录必须和<module>模块所处的目录</module>相一致。

7.习惯约定:为了方便构建,通常将聚合模块放在项目目录层的最顶层,其它聚合模块作为子目录存在。这样当我们打开项目的时候,第一个看到的就是聚合模块的POM

8.聚合模块减少的内容:聚合模块的内容仅仅是一个pom.xml文件,它不包含src/main/Java、src/test/java等目录,因为它只是用来帮助其它模块构建的工具,本身并没有实质的内容。

9.聚合模块和子模块的目录:他们可以是父子类,也可以是平行结构,当然如果使用平行结构,那么聚合模块的POM也需要做出相应的更改。

继承

我们在项目开发的过程中,可能多个模块独立开发,但是多个模块可能依赖相同的元素,比如说每个模块都需要Junit,使用spring的时候,其核心jar也必须都被引入,在编译的时候,maven-compiler-plugin插件也要被引入。这时我们采用继承,就不用在每个子模块分别定义了。

如何配置继承:

1.说到继承肯定是一个父子结构,那么我们在父工程中来创建一个parent project

2.<packaging>:作为父模块的POM,其打包类型也必须为POM

3.结构:父模块只是为了帮助我们消除重复,所以它也不需要src/main/java、src/test/java等目录

4.新的元素:<parent> , 它是被用在子模块中的

5.<parent>元素的属性:<relativePath>: 表示父模块POM的相对路径,在构建的时候,Maven会先根据relativePath检查父POM,如果找不到,再从本地仓库查找

6.relativePath的默认值: ../pom.xml

7.子模块省略groupId和version: 使用了继承的子模块中可以不声明groupId和version, 子模块将隐式的继承父模块的这两个元素

7 依赖管理

依赖范围是用来控制依赖与3种classpath(编译classpath,测试classpath,运行classpath)的关系。maven有以下几种依赖范围:

1、compile 编译、测试、运行,A在编译时依赖B,并且在测试和运行时也依赖。

       strus-core、spring-beans

       打成war包或jar包。

2、provided 编译、和测试有效,A在编译和测试时需要B。

       比如:servlet-api就是编译和测试有用,在运行时不用(tomcat容器已提供)。

       不会打成war

3、runtime:测试、运行有效。

       比如:jdbc驱动包 ,在开发代码中针对java的jdbc接口开发,编译不用。

       在运行和测试时需要通过jdbc驱动包(mysql驱动)连接数据库,需要的!!

       会打成war

4、test:只是测试有效,只在单元测试类中用。

       比如:junit

       不会打成war

如何设置依赖范围呢?

比如我们要将mysql驱动的依赖设置为runtime范围,配置如下:

<dependency>  <groupId>mysql</groupId>  <artifactId>mysql-connector-java</artifactId>  <version>5.1.6</version>  <scope>runtime</scope> </dependency>

将servlet依赖设置为provided

<dependency>  <groupId>javax.servlet</groupId>  <artifactId>servlet-api</artifactId>  <version>2.5</version>  <scope>provided</scope>  </dependency>

如果是compile就不需要设置了,因为compile是scope的默认值。

重新执行打包为war , 会发现servlet-api.jar已经不存在。

依赖传递

什么是依赖传递?

A->B(compile)     第一关系: a依赖b  compile

B->C(compile)      第二关系: b依赖c   compile

1、纵坐标:直接依赖

       A依赖B,B是A的直接依赖。

       在A的pom.xml中添加B的坐标。

2、横坐标:传递依赖

       B依赖C,C是A的传递依赖。

3、中间部分:传递依赖的范围,A依赖C的范围。



依赖调节原则

项目A依赖于项目B,项目B依赖于项目C(v1), 项目A依赖于项目D,项目D依赖于项目E,项目E依赖于C(v2),

1、A--->B---->C(v1) ,   

2、A------>D---->E----->C(v2)

项目A隐形依赖了两个版本的C,那到底采用哪个版本呢?

分析:

依赖调解第一原则路径优先,很明显,第一种路径深度是3,第二种路径深度是4,所以,maven会采用C(v1)

依赖调解第二原则:声明优先,假设路径深度相等,那么声明在前的会被引用。