zoukankan      html  css  js  c++  java
  • 项目1-maven

    Maven工程

    为什么要用Maven?

    添加第三方jar包

    使用Maven后每个jar包只在本地仓库中保存一份,需要jar包的工程只需要维护一个文本形式的jar包的引用——我们称之为“坐标”。不仅极大的节约了存储空间,让项目更轻巧,更避免了重复文件太多而造成的混乱

    jar包之间的依赖关系

    引入Maven后,Maven就可以替我们自动的将当前jar包所依赖的其他所jar包全部导入进来,无需人工参与,节约了我们大量的时间和精力。用实际例子来说明就是:通过Maven导入commons-fileupload-1.3.jar后,commons-io-2.0.1.jar会被自动导入,程序员不必了解这个依赖关系。

    处理jar包之间的冲突

    使用Maven就可以自动的处理jar包之间的冲突问题。因为Maven中内置了两条依赖原则:最短路径者优先和先声明者优先

    获取第方jar包

    使用Maven我们可以享受到一个完全统一规范的jar包管理体系。你只需要在你的项目中以坐标的方式依赖一个jar包,Maven就会自动从中央仓库进行下载,并同时下载这个jar包所依赖的其他jar包——规范、完整、准确!一次性解决所问题!

    将项目拆分成多个工程模块

    那么工程拆分后又如何进行互相调用和访问呢?这就需要用到Maven的依赖管理机制。大家请看我们的Survey调查项目拆分的情况:
    上层模块依赖下层,所以下层模块中定义的API都可以为上层所调用和访问。

    实现项目的分布式部署

    在实际生产环境中,项目规模增加到一定程度后,可能每个模块都需要运行在独立的服务器上,我们称之为分布式部署,这里同样需要用到Maven。

    什么是Maven?

    概念:

    Maven是一款自动化构建工具,专注服务于Java平台的项目构建和依赖管理。

    编译过程

    在实际项目中整合第方框架,Web工程中除了Java程序和JSP页面、图片等静态资源之外,还包括第方框架的jar包以及各种各样的配置文件。所这些资源都必须照正确的目录结构部署到服务器上,项目才可以运行。

    所以综上所述:构建就是以我们编写的Java代码、框架配置文件、国际化等其他资源文件、JSP页面和图片等静态资源作为“原材料”,去“生产”出一个可以运行的项目的过程。

    构建环节

    ①清理:删除以前的编译结果,为重新编译做好准备。

    ②编译:将Java源程序编译为字节码文件。

    ③测试:针对项目中的关键点进行测试,确保项目在迭代开发过程中关键点的正确性。

    ④报告:在每一次测试后以标准的格式记录和展示测试结果。

    ⑤打包:将一个包含诸多文件的工程封装为一个压缩文件用于安装或部署。Java工程对应jar包,Web工程对应war包。

    ⑥安装:在Maven环境下特指将打包的结果——jar包或war包安装到本地仓库中。

    ⑦部署:将打包的结果部署到远程仓库或将war包部署到服务器上运行。

    自动化构建

    那么Maven又是如何实现自动化构建的呢?简单的说来就是它可以自动的从构建过程的起点一直执行到终点:

    Maven核心环节

    Maven之所以能够实现自动化的构建,和它的设计是紧密相关的。我们对Maven的学习就围绕它的九个核心概念展开:

    POM

    Project Object Model:项目对象模型。将Java工程的相关信息封装为对象作为便于操作和管理的模型。Maven工程的核心配置。可以说学习Maven就是学习pom.xml文件中的配置。

    约定的目录结构

    现在JavaEE开发领域普遍认同一个观点:约定>配置>编码。意思就是能用配置解决的问题就不编码,能基于约定的就不进行配置。而Maven正是因为指定了特定文件保存的目录才能够对我们的Java工程进行自动化构建。

    坐标

    依赖管理

    1、概念
    当A jar包需要用到B jar包中的类时,我们就说A对B依赖。例如:commons-fileupload-1.3.jar依赖于commons-io-2.0.1.jar。

    通过第二个Maven工程我们已经看到,当前工程会到本地仓库中根据坐标查找它所依赖的jar包。

    配置的基本形式是使用dependency标签指定目标jar包的坐标。例如:

    <dependencies>
    
                                    <dependency>
    
                                                    <!—坐标 -->
    
                                                    <groupId>junit</groupId>
    
                                                    <artifactId>junit</artifactId>
    
                                                    <version>4.10</version>
    
                                                    <!-- 依赖的范围 -->
    
                                                    <scope>test</scope>
    
                                    </dependency>
    
                    </dependencies>
    
    
    

    2、依赖的范围
    当一个Maven工程添加了对某个jar包的依赖后,这个被依赖的jar包可以对应下面几个可的范围:

    ①compile

    [1]main目录下的Java代码可以访问这个范围的依赖

    [2]test目录下的Java代码可以访问这个范围的依赖

    [3]部署到Tomcat服务器上运行时要放在WEB-INF的lib目录下

    例如:对Hello的依赖。主程序、测试程序和服务器运行时都需要用到。

    ②test

    [1]main目录下的Java代码不能访问这个范围的依赖

    [2]test目录下的Java代码可以访问这个范围的依赖

    [3]部署到Tomcat服务器上运行时不会放在WEB-INF的lib目录下

    例如:对junit的依赖。仅仅是测试程序部分需要。

    ③provided

    [1]main目录下的Java代码可以访问这个范围的依赖

    [2]test目录下的Java代码可以访问这个范围的依赖

    [3]部署到Tomcat服务器上运行时不会放在WEB-INF的lib目录下

    例如:servlet-api在服务器上运行时,Servlet容器会提供相关API,所以部署的时候不需要。

    3、依赖的传递性
    当存在间接依赖的情况时,主工程对间接依赖的jar可以访问吗?这要看间接依赖的jar包引入时的依赖范围——只依赖范围为compile时可以访问。例如:

    4、依赖的原则:冲突的解决

    5、依赖的排除
    为了确保程序正确可以将可能重复的间接依赖排除。请看如下的例子:
    ·假设当前工程为survey_public,直接依赖survey_environment。
    ·survey_environment依赖commons-logging的1.1.1对于survey_public来说是间接依赖。
    ·当前工程survey_public直接依赖commons-logging的1.1.2
    ·加入exclusions配置后可以在依赖survey_environment的时候排除版本为1.1.1的commons-logging的间接依赖

    <dependency>
    
                    <groupId>com.atguigu.maven</groupId>
    
                    <artifactId>Survey160225_4_Environment</artifactId>
    
                    <version>0.0.1-SNAPSHOT</version>
    
                    <!-- 依赖排除 -->
    
                    <exclusions>
    
                                    <exclusion>
    
                                                    <groupId>commons-logging</groupId>
    
                                                    <artifactId>commons-logging</artifactId>
    
                                    </exclusion>
    
                    </exclusions>
    
    </dependency>
    
    <dependency>
    
                    <groupId>commons-logging</groupId>
    
                    <artifactId>commons-logging</artifactId>
    
                    <version>1.1.2</version>
    
    </dependency>
    
    
    

    6、统一管理目标jar包的版本

    以对Spring的jar包依赖为例:Spring的每一个版本中都包含spring-core、spring-context等jar包。我们应该导入版本一致的Spring jar包,而不是使用4.0.0的spring-core的同时使用4.1.1的spring-context。

    <dependency>
    
                    <groupId>org.springframework</groupId>
    
                    <artifactId>spring-core</artifactId>
    
                    <version>4.0.0.RELEASE</version>
    
    </dependency>
    
    <dependency>
    
                    <groupId>org.springframework</groupId>
    
                    <artifactId>spring-context</artifactId>
    
                    <version>4.0.0.RELEASE</version>
    
    </dependency>
    
    <dependency>
    
                    <groupId>org.springframework</groupId>
    
                    <artifactId>spring-jdbc</artifactId>
    
                    <version>4.0.0.RELEASE</version>
    
    </dependency>
    
    <dependency>
    
                    <groupId>org.springframework</groupId>
    
                    <artifactId>spring-orm</artifactId>
    
                    <version>4.0.0.RELEASE</version>
    
    </dependency>
    
    <dependency>
    
                    <groupId>org.springframework</groupId>
    
                    <artifactId>spring-web</artifactId>
    
                    <version>4.0.0.RELEASE</version>
    
    </dependency>
    
    <dependency>
    
                    <groupId>org.springframework</groupId>
    
                    <artifactId>spring-webmvc</artifactId>
    
                    <version>4.0.0.RELEASE</version>
    
    </dependency>
    
    
    

    问题是如果我们想要将这些jar包的版本统一升级为4.1.1,是不是要手动一个个修改呢?显然,我们统一配置的方式:

    <properties>
    
                    <spring.version>4.1.1.RELEASE</spring.version>
    
    </properties>
    
    <dependency>
    
                                                    <groupId>org.springframework</groupId>
    
                                                    <artifactId>spring-core</artifactId>
    
                                                    <version>${spring.version}</version>
    
                                    </dependency>
    
                                    <dependency>
    
                                                    <groupId>org.springframework</groupId>
    
                                                    <artifactId>spring-context</artifactId>
    
                                                    <version>${spring.version}</version>
    
                                    </dependency>
    
                                    <dependency>
    
                                                    <groupId>org.springframework</groupId>
    
                                                    <artifactId>spring-jdbc</artifactId>
    
                                                    <version>${spring.version}</version>
    
                                    </dependency>
    
                                    <dependency>
    
                                                    <groupId>org.springframework</groupId>
    
                                                    <artifactId>spring-orm</artifactId>
    
                                                    <version>${spring.version}</version>
    
                                    </dependency>
    
                                    <dependency>
    
                                                    <groupId>org.springframework</groupId>
    
                                                    <artifactId>spring-web</artifactId>
    
                                                    <version>${spring.version}</version>
    
                                    </dependency>
    
                                    <dependency>
    
                                                    <groupId>org.springframework</groupId>
    
                                                    <artifactId>spring-webmvc</artifactId>
    
                                                    <version>${spring.version}</version>
    
                                    </dependency>
    
    
    

    这样一来,进行版本调整的时候只改一改地方就行了。

    仓库管理

    1、仓库的分类
    [1]本地仓库:为当前本机电脑上的所Maven工程服务。
    [2]远程仓库
    (1)私服:架设在当前局域网环境下,为当前局域网范围内的所Maven工程服务。

    (2)中央仓库:架设在Internet上,为全世界所Maven工程服务。

    (3)中央仓库的镜像:架设在各个大洲,为中央仓库分担流量。减轻中央仓库的压力,同时更快的响应用户请求。

    2、仓库中文件

    [1]Maven的插件

    [2]我们自己开发的项目的模块

    [3]第方框架或工具的jar包

    ※不管是什么样的jar包,在仓库中都是照坐标生成目录结构,所以可以通过统一的方式查询或依赖。

    生命周期

    1、什么是Maven的生命周期
    Maven生命周期定义了各个构建环节的执行顺序,了这个清单,Maven就可以自动化的执行构建命令了。

    2、分类
    Clean Lifecycle在进行真正的构建之前进行一些清理工作。

    • Clean生命周期一共包含了三个阶段:

      ①pre-clean 执行一些需要在clean之前完成的工作
      ②clean 移除所上一次构建生成的文件
      ③post-clean 执行一些需要在clean之后立刻完成的工作

    • Default Lifecycle构建的核心部分,编译,测试,打包,安装,部署等等。

      Default生命周期是Maven生命周期中最重要的一个,绝大部分工作都发生在这个生命周期中。这里,只解释一些比较重要和常用的阶段:
    
            validate
    
            generate-sources
    
            process-sources
    
            generate-resources
    
            process-resources 复制并处理资源文件,至目标目录,准备打包。
    
            compile 编译项目的源代码。
    
            process-classes
    
            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将最终的包复制到远程的仓库,以让其它开发人员与项目共享或部署到服务器上运行。
    
    • Site Lifecycle生成项目报告,站点,发布站点。

      ①pre-site 执行一些需要在生成站点文档之前完成的工作

      ②site 生成项目的站点文档

      ③post-site 执行一些需要在生成站点文档之后完成的工作,并且为部署做准备

      ④site-deploy 将生成的站点文档部署到特定的服务器上

    这里经常用到的是site阶段和site-deploy阶段,用以生成和发布Maven站点,这可是Maven相当强大的功能,Manager比较喜欢,文档及统计数据自动生成,很好看。

    3、生命周期的自动化构建
    运行任何一个阶段的时候,它前面的所有阶段都会被运行,例如我们运行mvn install 的时候,代码会被编译,测试,打包。

    继承

    1、继承机制的使用原因
    由于非compile范围的依赖信息是不能在“依赖链”
    此时如果项目需要将各个模块的junit版本统一为4.9,那么到各个工程中手动修改无疑是非常不可取的。使用继承机制就可以将这样的依赖信息统一提取到父工程模块中进行统一管理。

    2、创建父工程
    创建父工程和创建一般的Java工程操作一致,唯一需要注意的是:打包方式处要设置为pom。

    3、在子工程中引用父工程

    <parent>
    
                    <!-- 父工程坐标 -->
    
                    <groupId>...</groupId>
    
                    <artifactId>...</artifactId>
    
                    <version>...</version>
    
                    <relativePath>从当前目录到父项目的pom.xml文件的相对路径</relativePath>
    
    </parent>
    
    <parent>
    
                    <groupId>com.atguigu.maven</groupId>
    
                    <artifactId>Parent</artifactId>
    
                    <version>0.0.1-SNAPSHOT</version>
    
                    
    
                    <!-- 指定从当前子工程的pom.xml文件出发,查找父工程的pom.xml的路径 -->
    
                    <relativePath>../Parent/pom.xml</relativePath>
    
    </parent>
    

    此时如果子工程的groupId和version如果和父工程重复则可以删除。

    4、在父工程中管理依赖
    将Parent项目中的dependencies标签,用dependencyManagement标签括起来

    <dependencyManagement>
    
                    <dependencies>
    
                                    <dependency>
    
                                                    <groupId>junit</groupId>
    
                                                    <artifactId>junit</artifactId>
    
                                                    <version>4.9</version>
    
                                                    <scope>test</scope>
    
                                    </dependency>
    
                    </dependencies>
    
    </dependencyManagement>
    

    在子项目中重新指定需要的依赖,删除范围和版本号

    <dependencies>
    
                    <dependency>
    
                                    <groupId>junit</groupId>
    
                                    <artifactId>junit</artifactId>
    
                    </dependency>
    
    </dependencies>
    

    聚合

    1、为什么使用聚合
    将多个工程拆分为模块后,需要手动逐个安装到仓库后依赖才能够生效。修改源码后也需要逐个手动进行clean操作。而使用了聚合之后就可以批量进行Maven工程的安装、清理工作。
    2、如何配置聚合
    在总的聚合工程中使用modules/module标签组合,指定模块工程的相对路径即可

       <modules>
                        <module>../Hello</module>
    
                        <module>../HelloFriend</module>
    
                        <module>../MakeFriends</module>
    
        </modules>
    

    3、创建MavenWeb工程的完美方式
    ①创建简单的Maven工程,打包方式war包

    ②调整JRE版本
    ③取消Dynamic Web Module的勾

    ④重新勾Dynamic Web Module

    ⑤点超链接进行必须设置

    ⑥最终生成的工程的结构 

    如何配置Maven?

  • 相关阅读:
    理解javascript观察者模式(订阅者与发布者)
    Javascript异步编程之setTimeout与setInterval详解分析(一)
    Gulp.js----比Grunt更易用的前端构建工具
    requireJS对文件合并与压缩(二)
    requireJS(版本是2.1.15)学习教程(一)
    Git使用教程
    Ajax基本知识
    go语言基础之有参有返回值函数的使用
    go语言基础之函数有多个返回值
    go语言基础之函数只有一个返回值
  • 原文地址:https://www.cnblogs.com/suit000001/p/13648624.html
Copyright © 2011-2022 走看看