首页 > 技术文章 > maven

wl-naruto 2018-05-27 00:55 原文

1、不用maven自动化构建工具,项目所存在问题
(1)一个项目就是一个工程
        如果项目非常大,就不适合用package来划分模块。最好是一个模块对应一个工程,利于分工。
        借助Maven,就可以将一个项目拆分成多个工程
(2)项目中所需要的jar包必须手动复制粘贴到WEB-INF/lib目录下
        带来的问题是同样的jar包文件重复出现在不同的项目工程中,一方面浪费存储空间,另外也让项目比较            臃肿
        借助Maven,可以将jar包仅仅保存在仓库中,有需要的项目“引用”这个文件接口,并不需要真的将jar
        包复制过来
(3)jar包需要别人为我们准本好,或者到官网下载
        借助maven可以以一种规范的方式下载jar包,因为所有知名框架或第三方jar包以一种规范的方式放在了
        maven的中央仓库中
(4)一个jar包依赖的其他jar包需要自己手动加入到项目中
        jar包之间的依赖关系都需要程序员自己了解清楚,那么极大的增加学习成本。
        借助maven,maven会自动的将jar包倒入进来
 
2、maven是什么
        (1)maven是一款服务于 java平台的的自动化构建工具
         发展历程:make—>Ant—>Maven—>gradle
         <1>构建:
            【1】概念:以“java原文件”、“jsp”、“HTML”、“图片”等资源为原材料,去“生产”一                个 可以运行的项目的过程
                ·编译
                ·部署
                ·搭建
            【2】编译:java原文件——>编译——>class字节码文件——>JVM执行
            【3】部署:一个bs项目最终运行的并不是动态web项目本身而是这个动态web项目"编译的结果"
        <2>构建过程中的各个环节
            【1】清理:将以前编译得到的旧的class字节码文件删除,为下一次编译做准备
            【2】编译:java源文件—>class字节码文件
            【3】测试:自动测试,自动调用junit程序
            【4】报告:测试程序执行的结果
            【5】打包:动态web工程打war包,java工程打jar包
            【6】安装:maven特定的概念,将打包得到的文件复制到“仓库”中的指定位置
            【7】部署:将动态web工程生成的war包复制到servlet容器的指定目录下,使其可以运行
        <3>自动化构建
3、maven的下载安装
(1)在apache-maven-3.2.2\conf\settings.xml文件中修改默認的本地倉庫的位置
<localRepository>D:\maven\RepMaven</localRepository>
 
(2)在apache-maven-3.2.2\conf\settings.xml文件中修改創建maven工程時,默認的jdk版本
  <profiles>   
   <profile>
        <id>jdk-1.7</id>
        
        <activation>
            <activeByDefault>true</activeByDefault>
            <jdk>1.7</jdk>
        </activation>
        
        <properties>
            <maven.compiler.source>1.7</maven.compiler.source>
            <maven.compiler.target>1.7</maven.compiler.target>
        </properties>
    </profile>
    
  </profiles>
 
 
 
 
4、maven的核心概念
(1)约定的目录
(2)POM
(3)坐标
(4)依赖
(5)仓库
(6)生命周期/插件/目标
(7)继承
(8)聚合
5、第一个maven工程
 
(1)创建约定的目录结构
    | 根目录:工程名
    |---|---|src目录:源码
    |---|---|---|main目录:存放主程序
    |---|---|---|---|java:存放java源文件
    |---|---|---|---|resources:存放框架或其他的配置文件
    |---|---|---|test目录:存放测试程序
    |---|---|---|---|java:存放java源文件
    |---|---|---|---|resources:存放框架或其他的配置文件
    |---|---|pom.xml:Maven的核心配置文件
6、常用的Maven命令
    (1)、注意:执行与构建过程相关的Maven命令,必须进入pom.xml所在的目录
            与构建过程相关:编译,测试,打包,部署
    (2)、常用的命令:
            【1】mvn clear:清理
            【2】mvn compile:编译主程序
            【3】mvn test-compile:编译测试程序
            【4】mvn test:执行测试
            【5】mvn package:打包
            【6】mvn install :安装
            【7】mvn site:生成站点
   (3)关于联网的问题
            【1】maven的核心程序中仅仅定义了抽象的生命周期,但是具体的工作必须有特定的插件完成,
                插件本身不包含在Maven的核心程序中。
            【2】当我们执行Maven的命令需要用到某些插件时,Maven首先会到本地仓库中查找
            【3】本地仓库的默认位置:c:\users\[登录当前系统的用户名]\.m2\repository
            【4】Maven核心程序如果在本地找不到需要的插件,那么会自动连接外网,到中央仓库下载
            【5】如果此时无法连接外网,则构建失败
            【6】修改默认的本地仓库位置:
                找到Maven的解压目录\conf\settings.xml
                在settings.xml文件中找到localRepository
                将标签体内的内容修改为已经准备好的Maven仓库目录
7、项目对象模型
    (1)POM含义:Project  Object  Model项目对象模型
    (2)pom.xml对于maven是核心配置文件,与构建过程相关的一切设置都在这个文件中进行配置。
            重要程度相当于web工程的web.xml
8、坐标
    (1)数学中的坐标
            【1】在平面上,使用x、y两个向量唯一定位平面中任何一个点
            【2】在空间上,使用x、y、z三个向量唯一定位空间中任何一个点
    (2)Maven的坐标
                使用下面三个向量在仓库中定位一个项目
            【1】groupid:公司或组织域名倒叙+项目名
                    <groupid>com.wl.naruto</groupid>
            【2】artifactid:模块的名称
                    <artifactid>maven</artifactid>
            【3】version:版本
                    <version>1.1.1</version>
    (3)Maven工程的坐标与仓库中路径对应的关系 
 
  <groupId>aopalliance</groupId>
  <artifactId>aopalliance</artifactId>
  <name>AOP alliance</name>
  <version>1.0</version>
aopalliance\aopalliance\1.0\aopalliance-1.0.jar
9、仓库
仓库的分类:
(1)、本地仓库:本地电脑上部署的仓库目录,为当前电脑上的 所有Maven项目服务
(2)、远程仓库
        【1】、私服: 搭建在局域网环境中,为局域网范围内的Maven项目服务
        【2】、中央仓库:架设在Internet上,为所有的Maven工程服务
        【3】、中央仓库的镜像:为了分担中央仓库的流量,提升用户的访问速度
仓库中包含的内容:
(1)、Maven自身所需要的插件
(2)、第三方框架或工具所需要的jar包
(3)、我们自己所开发的Maven工程
 
10、依赖
(1)、Maven解析依赖信息时会到本地仓库中查找被依赖的jar包。
        对于我们自己开发的Maven项目,使用Maven install 命令安装后就可以进入Maven仓库
(2)依赖的范围
        【1】compile:
                对主程序是否有效:有效
                对测试程序是否有效:有效
                是否参与打包:参与
                是否参与部署:参与
        【2】test:
                对主程序是否有效:无效
                对测试程序是否有效:有效
                是否参与打包:不参与
                是否参与部署:不参与
                典型的例子:junit
        【3】provided:
                对主程序是否有效:有效
                对测试程序是否有效:有效
                是否参与打包:不参与
                是否参与部署:不参与
                典型的例子:servlet-api.jar
 
11、生命周期
    (1)各个构建环节的这行顺序:不能打乱顺序,不需按照既定的正确顺序执行
    (2)Maven的核心程序中定义了抽象的生命周期,生命周期中各个阶段的具体任务室友插件来完成的
    (3) Maven 有三套相互独立的生命周期, 分别是:
            【1】Clean Lifecycle 在进行真正的构建之前进行一些清理工作。
            【2】Default Lifecycle 构建的核心部分,编译,测试,打包,安装,部署等等。
            【3】Site Lifecycle 生成项目报告,站点,发布站点
 
              它们是相互独立的,你可以仅仅调用 clean 来清理工作目录,仅仅调用 site 来生成站点。 当然你也可以直接运行 mvn clean install site 运行所有这三套生命周期 , 每套生命周期都由一组阶段(Phase)组成,我们平时在命令行输入的命令总会对应于一个特定的阶段。比如,运行 mvn clean,这个 clean 是 Clean 生命周期的一个阶段。有 Clean 生命周期,也有 clean 阶段
    (4)、 Clean 生命周期
            Clean 生命周期一共包含了三个阶段:
            【1】pre-clean 执行一些需要在 clean 之前完成的工作
            【2】clean 移除所有上一次构建生成的文件
            【3】post-clean 执行一些需要在 clean 之后立刻完成的工
    (5)、 Site 生命周期
            ①pre-site 执行一些需要在生成站点文档之前完成的工作
            ②site 生成项目的站点文档
            ③post-site 执行一些需要在生成站点文档之后完成的工作,并且为部署做准备
            ④site-deploy 将生成的站点文档部署到特定的服务器上
 
            这里经常用到的是 site 阶段和 site-deploy 阶段,用以生成和发布 Maven 站点,这可是 Maven 相当强大的功能
     (6)、 Default 生命周期
            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 将最终的包复制到远程的仓库,以让其它开发人员与项目共享或部署到服务器上运行
    (7)、 生命周期与自动化构建
             运行任何一个阶段的时候,它前面的所有阶段都会被运行, 例如我们运行 mvn install 的时候,代码会被编译,测试,打包。 这就是 Maven 为什么能够自动执行构建过程的各个环节的原因。此外, Maven 的插件机制是完全依赖 Maven 的生命周期的,因此理解生命周期至关重要
      (8) 插件和目标
            【1】Maven 的核心仅仅定义了抽象的生命周期,具体的任务都是交由插件完成的。
            【2】每个插件都能实现多个功能,每个功能就是一个插件目标。
            【3】Maven 的生命周期与插件目标相互绑定,以完成某个具体的构建任务。
例如: compile 就是插件 maven-compiler-plugin 的一个目标; pre-clean 是插件 maven-clean-plugin 的一个目
 
12、依赖【高级】
    
   (1)、依赖的传递性
        【1】好处:可以传递的依赖不必再每个模块工程中都重复声明,只需要在最下面的工程中依赖一次
        【2】注意:非compile范围内的依赖不能传递,所以在各个工程模块中,如果需要就得重复声明 
 
    (2)、依赖的排除
        【1】依赖排除的设置方式
 
<!-- 依赖的排除 -->
         <exclusions>
             <exclusion>
                 <groupId>commons-logging</groupId>
                 <artifactId>commons-logging</artifactId>
             </exclusion>
         </exclusions>
(3)、依赖的原则(内部机制)--解决模块工程之间jar包冲突
        【1】、路径最短者优先
 
 
 
 
        【2】、先声明者 优先
 
(4)统一管理依赖的版本号
    【1】在<properties>内自定义标签名,内容为版本号
 
 <properties>
      <com.naruto.spring.version>4.0.0.RELEASE</com.naruto.spring.version>
  </properties>
    【2】 引用前面声明的版本号
 
<dependencies>
   <dependency>
      <groupId>org.springframework</groupId>
      <artifactid>spring-core<artifactid>
     <version>${com.naruto.spring.version}</version>
   </dependency>
</dependencies>
 
 
13.继承
    (1)为什么需要继承机制?
        由于非 compile 范围的依赖信息是不能在“依赖链”中传递的, 所以有需要的工程只能单独配置。
    (2)开发步骤
            【1】 在父工程中管理依赖( 创建父工程和创建一般的 Java 工程操作一致,唯一需要注意的是: 打包方式处要设置为 pom)
 
<!-- 统一配置依赖的管理-->
  <dependencyManagement>
    <dependencies>
         <dependency>
             <groupId>junit</groupId>
             <artifactId>junit</artifactId>
             <version>4.9</version>
             <scope>test</scope>
         </dependency>
    </dependencies>
  </dependencyManagement>
 
            【2】 在子工程中引用父工程
 
 <!-- 子工程声明父工程 -->
  <parent>
    <groupId>com.naruto.maven</groupId>
    <artifactId>Parent</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <!-- 以当前文件为基准 的父工程 的的pom.xml的相对路径 -->
    <relativePath>../Parent/pom.xml</relativePath>
  </parent>
            【3】 在子项目中重新指定需要的依赖,删除范围和版本号
 
<dependency>
   <groupId>junit</groupId>
   <artifactId>junit</artifactId>
   <scope>test</scope>
</dependency>
17、聚合
    (1)作用:一键安装各个模块工程
    (2)配置方式:在一个总的聚合工程中配置参与聚合的各个模块
 
<!-- 配置聚合 -->
  <modules>
    <!-- 指定各个子工程的相对路径 -->
    <module>../Hello</module>
    <module>../HelloFriend</module>
    <module>../MakeFriend</module>
  </modules>
18、web工程的部署
    
 
    <!-- 配置构建工程中需要使用的插件 -->
    <build>
         <!-- 部署项目时的名称 -->
         <finalName>NarutoWeb</finalName>
         <plugins>
             <plugin>
                 <!-- cargo是一家专门从事启动servlet容器的组织 -->
                 <groupId>org.codehaus.cargo</groupId>
                 <artifactId>cargo-maven2-plugin</artifactId>
                 <version>1.2.3</version>
                 <!-- 针对插件做的配置 -->
                 <configuration>
                      <!-- 配置当前系统中容器的位置 -->
                      <container>
                          <containerId>tomcat7x</containerId>
                          <home>D:\Tomcat\apache-tomcat-7.0.82</home>
                      </container>
                      <configuration>
                          <type>existing</type>
                          <home>D:\Tomcat\apache-tomcat-7.0.82</home>
                          <!-- 如果Tomcat端口为默认值8080则不必设置该属性 -->
                          <!-- <properties>
                              <cargo.servlet.port>8080</cargo.servlet.port>
                          </properties> -->
                      </configuration>
                 </configuration>
                 <!-- 配置插件在什么情况下执行 -->
                 <executions> 
                      <execution> 
                          <id>cargo-run</id>
                          <!-- 生命周期的阶段 -->
                          <phase>install</phase> 
                          <goals>
                               <!-- 插件的目标 --> 
                               <goal>run</goal> 
                          </goals> 
                      </execution> 
                 </executions>
             </plugin>
         </plugins>
    </build>
 
 
 
 
 
 
 
 
   
 
 
 
 
 
 
 
 
 
 
 
 
 
 
            
            
 
    
 
 
                  
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
        
    
    
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

推荐阅读