Maven核心概念和平常实践

1、Maven

1.1 为何写Maven

工欲善其事,必先利其器。现在Java相关开发,基本离不开Maven、Gradle、MAT、Hudson之类的玩意,因此把本文看成工具篇吧,后续有空再整理其余工具。java

1.2 概述

Maven是优秀的构建工具,但不只仅是能构建,还有着强大的仓库管理、项目管理相关的功能。我这介绍这一句话,像详细了解它的全部描述或者构建工具的介绍,请自行百度谷歌或参考官网。spring

1.3 安装

依赖JDK:下载JDK的压缩包,解压,配置环境变量JAVA_HOME=安装目录、PATH=$JAVA_HOME/bin:$PATH 即完成。
安装Maven:一样下载Maven的压缩包,解压,配置MAVEN_HOME=安装目录、PATH=$MAVEN_HOME/bin:$PATH 即完成。
检查JDK : java -version 。 检查Maven: mvn -version。
安装后须要了解的是:Maven项目最核心就是pom.xml文件(建立项目后才有),须要在项目中配置的就是配置在pom文件中,还有少数全局配置是配置在maven安装目录中conf下的setting.xml中。apache

1.4 经常使用Maven网站

注:国内镜像也有好些,能够本身找。由于周边大多数人都用了开源中国的镜像,因此我这边也推荐它。ui

1.5 建立Maven项目

(1)了解建立符合maven规范的项目结构,即src/main/java、src/main/resources那套。
(2)建立pom.xml文件。
(3)命令行能够经过Archetype命令生成项目骨架。Eclipse等IDE集成Maven后也能够建立Maven项目(推荐!!! )。
(4)经常使用命令
图片描述url

1.6 Pom文件变量属性

maven定义了不少变量,常见的maven属性,了解下本身可用,阅读其余项目的时候可看懂。
${basedir} 项目根目录
${project.name}项目名
${project.version}项目版本号
${project.groupId}项目groupId
${project.build.directory} target目录
${project.build.finalName} 打包的名字spa

2、依赖管理

2.1 概述

经过在pom.xml配置依赖坐标,Maven会自动帮咱们下载依赖的构件。
Maven的依赖主要是经过groupId、artifactId和version三者一块儿来肯定一个构件的坐标。

2.2 例子

<dependencies>
    <dependency>
        <groupId>junit</groupId>         <!-- groupId 公司和组织的标识 -->
        <artifactId>junit</artifactId>   <!-- artifactId 项目或者模块ID,在该groupID下必须惟一 -->
        <version>4.10</version>          <!-- version 版本号,带SNAPSHOT为快照版本 -->
        <scope>test</scope>              <!-- scope 依赖范围,默认为compile -->
        <exclusions>                     <!-- exclusions 用来排除传递性依赖 -->
           <exclusion>                   <!-- exclusions指定排除的依赖的groupId和artifactId -->
           ....
           </exclusion>
        </exclusions>
    </dependency>
<dependencies>

图片描述

2.3 关于dependencyManagement

这个标签主要起到依赖统一管理的做用。通常maven开发多个项目的时候,都会建立一个parent父模块来配置pom文件统一管理公用的东西,(下面聚合和继承就是讲这部分)。在dependencyManagement下也是经过在dependencies标签下配置依赖的,但它上面在dependencies标签配置不一样。

不一样之处是:在dependencyManagement中配置了,项目并不会直接下载依赖的构件,而是要在子模块或者当前模块的dependencies中进行配置,代表当前模块须要用到的依赖,但此时就不用再指定版本号了。dependencyManagement也是以此来确保各个模块对相同构件能够用同一版本,也就利于统一升级版本号等等。

<dependencyManagement> <!-- 能够把它当作构件的版本声明,并不会引起下载 -->
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>3.2.5.RELEASE</version>
        </dependency>
    </dependencies>
</dependencyManagement>
<dependencies>    <!-- 必须配置它才会进行依赖下载 -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
    </dependency>
</dependencies>

3、仓库

3.1 本地仓库

本地仓库没啥好说的,在maven安装目录下的conf/setting.xml中配置localRepository就能够指定路径。默认路径则是在用户根目录下的.m2/repository。
做用:maven编译模块的时候,依赖的模块都会按照本地->远程(通常是私服)->中央的顺序依次查找构件。日常开发的模块也是经过mvn install安装到本地仓库,其余编译时才能使用;而若是跟其余人合做开发则要经过deploy发布到远程仓库。发布后,别人下载依赖也会将经过远程或者中央仓库下载来的构件保存到别人的本地仓库。

<localRepository>D:\repository</localRepository>

3.2 远程仓库

通常在项目中,会在<repositories>标签下配置远程仓库,能够配置多个,但id必须惟一。中央仓库默认的id为central,能够不用配置;但若是有其余仓库用这个id,则会覆盖中央仓库。(不过,像通常公司都会本身搭建私服,因此也能够把central覆盖成咱们私服的仓库,咱们也这样作)。
在pom.xml中配置远程仓库的例子以下:

<repositories>
     <repository>
         <id>repo.springsource.org</id>
         <name>repo.springsource.org-releases</name>
         <url>http://repo.springsource.org/libs-milestone-local</url>
         <snapshots>
             <enabled>false</enabled>
         </snapshots>
    </repository>
    <repository>
        <id>nexus</id>   <!-- 私服仓库 -->
        <name>TeamNexusRepository</name>
        <url>http://localhost:8081/nexus/content/groups/public</url>
        <releases>
            <enabled>true</enabled>
        </releases>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
        <layout>default</layout>
    </repository>
    ...
</repositories>

另外还能够指定插件的仓库:

<pluginRepositories> 
    <pluginRepository> 
        <id>nexus</id>
        <name>TeamNexusRepository</name>
        <url>http://localhost:8081/nexus/content/groups/public</url> 
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
    </pluginRepository>
</pluginRepositories>

在pom.xml中配置的远程仓库,只会在pom文件对应的模块有效,即便配置在parent的pom中用来被继承,那也只是当前项目各个模块有效。若是多个项目实际上都想用同样的远程仓库(实际场景就是私服),那须要在setting.xml中利用profile来进行配置。
在setting.xml中配置远程仓库的例子以下:

<profiles>
    <profile>
      <id>nexus</id>
      <repositories>
        <repository>
          <id>central</id>
          <url>http://localhost:8081/nexus/content/groups/public/</url>
        </repository>
      </repositories>
      <pluginRepositories>
        <pluginRepository>
          <id>central</id>
          <url>http://localhost:8081/nexus/content/groups/public/</url>
        </pluginRepository>
      </pluginRepositories>
    </profile>
</profiles>

<activeProfiles> <!-- 激活profile -->
    <activeProfile>nexus</activeProfile>
</activeProfiles>

3.3 仓库镜像

除了以上配置以外,咱们还能够在setting.xml里面配置仓库的镜像,通常用于当访问某个仓库的时候,可能因为网络不一样或者其余缘由须要转换到另一个地址,这个时候就能够配置这个仓库的镜像。例如你想覆盖中央仓库的默认地址,能够在setting.xml里面这样配置:

<mirrors>     
     <mirror>     
       <id>maven-net-cn</id>     
       <name>MavenChinaMirror</name>     
       <url>http://maven.net.cn/content/groups/public/</url>     
       <mirrorOf>central</mirrorOf>     
     </mirror>     
</mirrors>

这里经过<mirrorOf>标签指定为central仓库作镜像,就是访问central的url再也不是国外那个地址,而会被转为咱们配置的镜像地址http://maven.net.cn/content/groups/public/ (也能够配置为私服地址等等), 而若是想为全部的仓库作镜像那么能够改成 <mirrorOf>*</mirrorOf>。
在个人项目中,因为通常会把central设置为咱们的私服仓库,因此大部分状况下也就不用配置镜像了。若是确实有多个仓库的话,那确实能够用<mirrorOf>*</mirrorOf>的方式指向私服。

3.4 发布到仓库

<distributionManagement>
    <repository>
        <id>nexus</id>
        <name>releases</name>
        <url>http://localhost:8081/nexus/content/groups/public/</url>
    </repository>
    <snapshotRepository>
        <id>nexus</id>
        <name>snapshots</name>
        <url>http://localhost:8081/nexus/content/groups/public/</url>
    </snapshotRepository>
</distributionManagement>

4、插件

4.1 概述

4.2 生命周期

4.3 常见插件

4.4 例子

4.5 关于pluginManagement

这个标签跟dependencyManagement标签同样,也是为了起到统一管理的做用,只是它统一管理了插件。跟依赖管理同样,通常也会在parent父模块来配置pom来配置pluginManagement,统一描述好插件以后,在子模块中就不用完整的配置插件已经绑定的生命周期和执行目标等等,只须要指定插件的groupId 和 artifactId就能够完成插件的引用。下面给出例子。
父模块(parent模块)的pom.xml中配置:

<build>
    <pluginManagement>
        <plugins>
           <plugin>
              <groupId>org.apache.maven.plugins</groupId>
              <artifactId>maven-source-plugin</artifactId>
              <version>2.4</version>
              <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
              </executions>
            </plugin>
          </plugins>
    </pluginManagement>
    <!-- 若是父模块这里配置的话,则全部子模块都会引用该插件!!因此通常只用于通用插件。
    <plugins>  
       <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-source-plugin</artifactId>
       </plugin>
    </plugins>
    -->
</build>

其余子模块须要单独引用插件的,能够在pom.xml中配置:

<build>
    <plugins>
       <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-source-plugin</artifactId>
       </plugin>
    </plugins>
</build>

5、聚合和继承

5.1 继承

先说继承吧,其实继承就是为了抽出相同的东西,而后给项目的其余模块一块儿共用,而不用每一个模块的pom.xml文件都写不少重复的东西。若是光说重复的工做量也就算了,有个重点是相似spring-core这种多个模块均可能用到的依赖,若是每一个模块都本身配置本身的依赖和版本好,那很容易就会犯错或者依赖的版本不一致致使错误等等。所以,在拆分多模块开发的时候,尽可能考虑使用继承。

如何使用Maven继承呢?
(1)创建一个文件夹,只建立一个pom.xml文件便可。
(2)而后把各个模块通用的东西写到这个pom.xml中,如属性定义,工厂定义,依赖坐标定义等等。
(3)把这个pom.xml中的<packaging>的值设置为pom。
(4)在各个子模块中使用<parent>标签指明本身使用的父项目。

关于父模块的依赖配置注意两点:
(1)通常都是经过<dependencyManagement>来配置全部依赖及其版本号,而后子模块,在本身的pom文件中声明依赖便可,不用再指定版本,以确保统一。
(2)父项目中何时直接配置<dependencies>呢?就是肯定每一个子模块基本都会用的依赖,统一配置,不用每一个子模块再单独去配的,好比junit、log4j这种。

5.2 聚合

聚合的做用在于能够把一个项目的多个模块一块儿配置,这样能够一次性编译、安装和发布多个模块。
通常项目都会把聚合和继承都会放到同一个pom.xml文件进行管理。

如何使用Maven聚合呢?
(1)创建一个文件夹,只建立一个pom.xml文件。
(2)而后在这个pom.xml文件中,把这个pom.xml中的<packaging>的值设置为pom和配置<modules>标签便可。

若是其余模块跟父pom.xml是同一层的话,以下图:
图片描述
则模块的配置方式为:

<modules>
    <module>hello-world</module>
    <module>hello-spring</module>
</modules>

6、插件开发

待更新

相关文章
相关标签/搜索