内源分析项目:可爱的Maven

说道Maven,恩,我要说的是《星际漫游指南》中那个患有忧郁症的机器人。[read more=”点击阅读更多” less=”收起阅读”]

 

哎不对, 今天说的是另一个Maven,用来管理工程的小Maven。

江湖人送外号:项目管理小专家。Maven这个词来自犹太语的欧系分支,意思是传道授业解惑的某个特定领域内专家,knowledge accumulator。

怎么比喻Maven最好呢…

假设一个IOS程序员想发布一个APP,他会做什么?

  1. 设计APP的界面和交互效果
  2. 设计业务逻辑
  3. 完成客户端业务逻辑代码
  4. 完成服务器端业务逻辑代码
  5. 发布 碉堡了.app  到appstore

Maven能做到的就是帮助你更好的完成 3,4,5这三个步骤。

现代应用的开发和建筑工程类似,我们总是会使用第三方的零件或解决方案。Maven本身也是一个解决方案。它包括两个重要组成部分:

  1. 灵活构建工程的一套流程
  2. 可以获取零件需要的零件仓库,可以想象成某宝免费版。

这样看来可以把Maven比喻成一个: 建筑承包商,而且是免费服务!

既然是建筑承包商,我们肯定得下达需求,下达目标。

接下来看看,Maven是如何通过 POM任务清单 来下达订购需求和制定构建目标。

POM清单

POM(Project Object Model), 在到处找对象的世界,一切都是对象。工程管理也不外如此。POM就是项目经理的工作列表。我们在POM文件中列出组件订购清单,并制定我们的装配目标。商品生产出来后,发货到什么地方。甚至告诉机器如何测试半成品,测试半成品。简单说POM有以下两个主要组成部分。

  1. 我们需要的零件(依赖,插件),插件用来达成什么目标。
  2. 我们要发布的产品名称和类型。 (如:碉堡了.app; 酷毙了.war; 王思聪.jar)

言归正传,看看内源分析项目中我们怎么去下发这个需求的。下面列出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>       
  <!-- Maven的版本 -->
  <groupId>com.huawei.xdu</groupId>        
  <!-- 商品上架到哪个领域下 -->
  <artifactId>ArthurAppEngine</artifactId> 
  <!-- 商品名称 -->
  <version>1.0-SNAPSHOT</version>          
  <!-- 商品版本 -->
  <packaging>war</packaging>               
  <!-- 确定是 碉堡了.app 还是 酷毙了.war  -->
  <distributionManagement>                 
  <!-- 你的商品是否要上架到某宝所需的某宝地址  -->
    <repository>
      <id>baba_mayun</id>
      <name>Maven China Mirror</name>
      <url>http://maven.aliyun.com/nexus/content/groups/public</url>
    </repository>
</distributionManagement>
  <parent>                                  
    <!-- 该商品的父商品 springboot 指定  -->
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.4.0.RELEASE</version>
  </parent>

  <dependencies> <!-- 该商品要用到的零件  -->

    <dependency>
      <groupId>org.apache.tomcat.embed</groupId>   
      <!-- 一个嵌入的tomcat容器  -->
      <artifactId>tomcat-embed-jasper</artifactId>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>    
      <!-- spring框架的web启动 -->
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>    
      <!-- springboot处理页面引擎时要用到thymeleaf -->
      <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    <dependency>
      <groupId>org.thymeleaf</groupId>  
      <!-- thymeleaf功能实现的主要实现者 xml parser -->
      <artifactId>thymeleaf</artifactId>
      <version>3.0.6.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.thymeleaf</groupId>     
      <!-- thymeleaf的spring胶水代码包 -->
      <artifactId>thymeleaf-spring4</artifactId>
      <version>3.0.6.RELEASE</version>
    </dependency>
    <dependency>
    <groupId>nz.net.ultraq.thymeleaf</groupId>   
    <!-- 使用thymeleaf的布局功能时要用到的依赖 -->
    <artifactId>thymeleaf-layout-dialect</artifactId>
    <version>2.1.2</version>
  </dependency>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>  
      <!-- mac下我使用了mysql,实际项目用到sql server -->
      <version>5.1.9</version>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-devtools</artifactId>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-jdbc</artifactId> 
      <!-- 数据库的 jdbc 引擎支持-->
    </dependency>

    <dependency>
      <groupId>io.springfox</groupId>
      <artifactId>springfox-swagger2</artifactId>  
      <!-- 自动文档生成零件 swagger.用注解写文档 -->
      <version>2.6.1</version>
    </dependency>
    <dependency>
      <groupId>io.springfox</groupId>
      <artifactId>springfox-swagger-ui</artifactId>  
       <!-- 注解写的文档用web展示出来 -->
      <version>2.6.1</version>
    </dependency>
    <dependency>
      <groupId>c3p0</groupId>        
      <!-- 一个神奇的组件,连接各种数据库时用,在xml中指定数据连接信息 -->
      <artifactId>c3p0</artifactId>
      <version>0.9.1.1</version>
    </dependency>
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate</artifactId>  
      <!-- hibernate支持  -->
      <version>3.2.5.ga</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-orm</artifactId>   
      <!-- 用来解析hibernate的bean  -->
      <version>3.2.5.RELEASE</version>
    </dependency>


  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <!-- 对了,到处是胶水零件,这个是springboot和maven配合  -->
        <artifactId>spring-boot-maven-plugin</artifactId> 
        <!-- 这样你就可以用命令行 mvn spring-boot:run 跑起程序  -->
        <version>1.5.4.RELEASE</version>
        <executions>
           <execution>
              <goals>
              <goal>repackage</goal>
              </goals>
           </execution>
         </executions>
    </plugin>
    </plugins>

    <resources>
      <resource>
        <directory>resources/</directory>    
        <!-- POM老大说:如果项目下有些后缀的文件就不要关心 -->
        <excludes>
          <exclude>**/*.java</exclude>
          <exclude>**/.git/*</exclude>
        </excludes>

        <filtering>false</filtering>
      </resource>

    </resources>

  </build>
</project>

分解POM任务清单

分解一:工程基本配置project

一个完整POM任务清单文件最小配置得包含:

<project>
<modelVersion>4.0.0</modelVersion>       
<!-- Maven的版本 -->
<groupId>com.arthur.opensource-digger</groupId>        
<!-- 商品上架到哪个领域下 -->
<artifactId>ArthurAppEngine</artifactId> 
<!-- 商品名称 -->
<version>1.0-SNAPSHOT</version>          
<!-- 商品版本 -->
<packaging>war</packaging>
<!-- 商品的打包类型,非必须 -->
</project>
  • <project> 作为项目描述的开头
  • modelVersion – 固定为4.0.0版本,说明Maven当前的任务清单格式版本
  • groupId – 项目的分组ID,一个项目可能存在多个group
  • artifactId – 项目的零件ID,一个项目可能存在多个零件
  • version – 指定项目组ID下某个零件ID的具体版本号
  • packaging – 打包类型,非必须。如果没有添加,默认是jar

患有忧郁症的项目经理Maven,收到这个任务清单后,会制作出一个叫做ArthurAppEngine-1.0-SNAPSHOT.war 的 app了。

看到这里,可能你会有疑问。

如果在项目中用了这个迷你POM,他怎么去取到我所需要的基本依赖呢?Maven作为一个老司机早就想到这一点。工程中所有的POM文件都继承Maven安装目录的pom.xml配置–俗称 super pom。

这个超级POM文件会让你即使没指定POM下载目录依然有一个可以获取零件的仓库地址:http://repo.maven.apache.org/maven3。

分解二:宿主项目PARENT

groupId,artifactId  作为 项目(project) 的一部分,在Maven中可以定义多份。多个{groupId.artifactId} 组合为一个 project,可以其中一个{groupId}作为家长/父组件(parent),其它的{groupId}作为模块。每个{groupId.artifactId} 也可以单独制作出一个发布件。按照这种规则,在项目中灵活制作自己的零件和模块,最后组成一个完整的软件工程。

内源分析项目的parent指定如下:

<parent>                                  
  <!-- 当前项目(ArthurAppEngine)的父组件groupId(spring-boot-starter-parent) -->
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-parent</artifactId>
  <version>1.4.0.RELEASE</version>
</parent>

大家看清楚了,我们的项目就继承自 spring-boot-starter-parent 。这说明项目启动时,父项目要先启动,然后再是启动到我们的业务流程。

分解三:依赖DEPENDENCY

当流程跑到我们的代码时,我们也会去主动依赖一些第三方的工具,这时候dependency就发挥了作用。

<dependencies> 
    
    <!-- 重点依赖一:一个嵌入的tomcat容器  -->
    <dependency>
      <groupId>org.apache.tomcat.embed</groupId>   
      <artifactId>tomcat-embed-jasper</artifactId>
      <scope>provided</scope>
    </dependency>

    <!-- 重点依赖二:spring mvc框架的web启动 -->
    <dependency>
      <groupId>org.springframework.boot</groupId>    
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- 重点依赖三:springboot处理页面引擎时要用到thymeleaf -->
    <dependency>
      <groupId>org.springframework.boot</groupId>    
      <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
     
    <!-- 重点依赖四:thymeleaf功能实现的主要实现者 xml parser -->
    <dependency>
      <groupId>org.thymeleaf</groupId>  
      <artifactId>thymeleaf</artifactId>
      <version>3.0.6.RELEASE</version>
    </dependency>
 
    <!-- 重点依赖五:mac下我使用了mysql,实际项目用到sql server -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>  
      <version>5.1.9</version>
    </dependency>

    <!-- 重点依赖六:数据库的 jdbc 引擎支持-->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-jdbc</artifactId> 
    </dependency>

    <!-- 重点依赖七:一个神奇的组件c3p0,连接各种数据库时用,在xml中指定数据连接信息 -->
    <dependency>
      <groupId>c3p0</groupId>        
      <artifactId>c3p0</artifactId>
      <version>0.9.1.1</version>
    </dependency>

  </dependencies>

分解四:下载镜像源MIRROR

依赖介么多包,是需要从Maven的仓库下载的,为了下载速度,配置Maven的中国镜像。如果没有配置,默认下载到.m2/repository目录下。

  • mac下位于 ~/.m2/settings.xml。
  • windows下位于 C:/users/{yourname}/.m2/settings.xml
<?xml version="1.0" encoding="UTF-8"?>
 2 <settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
 3           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4           xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd    /settings-1.0.0.xsd">
 5 <mirrors>
 6 <mirror>
 7 <id>aliyun</id>
 8 <mirrorOf>central</mirrorOf>
 9 <name>alimaven</name>
10 <url>http://maven.aliyun.com/nexus/content/repositories/central/</url>
11 </mirror>
12 </mirrors>
13 </settings>

运行项目

万事具备了,接下来等待我们的是下发命令。让代码飞起来!

运行

mvn spring-boot:run

跑起程序。

或者用

mvn install

生产出你的app:  ArthurAppEngine-1.0-SNAPSHOT.war

发布项目

app马上就要做出来了,该发布到哪去呢?分发管理distributionManager就是指定发布位置的,在POM.xml中。

  <distributionManagement>                 
  <!-- 你的商品是否要上架到某宝所需的某宝地址  -->
    <repository>
      <id>baba_mayun</id>
      <name>Maven China Mirror</name>
      <url>http://maven.aliyun.com/nexus/content/groups/public</url>
    </repository>
</distributionManagement>

Maven中的两个重要概念:Phase和LifeCycle

以上是内源分析项目中的基本POM配置和说明。但这还远远不够,甚至只是说刚刚开始。只是对于我们的内源分析工程已经够用。

对于Maven最重要概念之一是:  Phase (构建阶段)

PHASE|构件阶段

老司机Maven先生把一个项目构建分解为以下几个主要阶段:

  1. validate – 验证阶段,验证工程是否正确,是否已经拿到所有需要的信息。
  2. compile -编译代码和复制资源到target目录。
  3. test – 使用某种测试框架测试我们的业务流程。测试用例不能要求业务代码已经被打包或部署。
  4. package – 把编译后的代码及其资源打包为一个可用的app(jar包,war包)
  5. verify – 将发布的包用于集成测试,验证包作为一个组件是否满足业务需求。
  6. install -将编译出来的包安装到本地仓库(settings.xml指定的repository路径。默认在.m2目录下),用于作为其它本地工程的依赖。
  7. deploy – 实实在在的把自己的产品拿出去见人,发布到pom.xml中指定的发布路径。供网上其它项目和工程使用。

每调用上面任一个步骤,其前所有步骤都会调用。

LIFECYCLE|生命周期

7个Phase合起来叫做: LifeCycle(构建的生命周期)。 这是Maven中另一个重要概念。

又到发问时间,既然有一个LifeCycle,也会有很多LifeCycle啊!

没错。Maven有三个LifeCycle,上面是最重要的 默认lifecylce。几乎每个项目都会用到。

此外还有

clean lifecycle:

pre-clean 在清理项目生成文件前执行某些依赖的程序
clean 清理上次所有生成文件
post-clean 项目清理完后的扫尾操作,比如把某个环境变量设置回去

Site Lifecycle:

pre-site site命令前执行一些进程,比如起某个服务进程。用于图片压缩。
site 生成我们的web
post-site 中间步骤,生成站点后的收尾。站点部署前准备脚本。
site-deploy 部署站点到我们的web服务器

不过这并没在内源分析项目中使用。

全文完。

———————————————————-

有兴趣的朋友可以添加微信和我交流。觉得学到了一些东西的不妨打赏下吧^_^。

微信号:GoodWillDo 打赏专用。支持鼓励,不在多少

[/read]

发表评论

电子邮件地址不会被公开。 必填项已用*标注