开发者社区> uyang> 正文

换个视角看Maven - 一个领域平台的优美设计

简介:
+关注继续查看

该文章来自阿里巴巴技术协会(ATA)精选集

作为一个java程序员,Maven是再熟悉不过的工具了, 它提供了构建项目的一个框架, 在默认情况下为我们提供了许多常用的Plugin,其中便包括构建Java项目的Plugin,还有War,Ear等。除此之外还提供内建的项目生命周期管理。 
20140824202302102

以上是我们最熟悉的maven的一面。 下面我们要从领域平台设计的角度,分析Maven的优美设计,为我们做领域平台化提供参考,最后我们再来思考如何做招商的领域平台。

Maven是领域驱动设计实现的,作为一个强大的项目管理构建平台而实现

我们先会介绍maven的基本模型,概念以及功能。 然后我们在分析这个领域平台在领域设计上的一些亮点。最后我们再延伸思考,如果用maven的思路我们可以在阿里的业务系统平台化中得到什么启示。

Maven的用途,核心概念,用法,扩展等

Maven的基本介绍

Maven 是 Apache 组织下的一个通用项目管理工具,它主要用来帮助实现项目的构建、测试、打包和部署。**Maven 提供了标准的软件生命周期模型和构建模型,通过配置就能对项目进行全面的管理。它Maven 将构建的过程抽象成一个个的生命周期过程,在不同的阶段使用不同的已实现插件来完成相应的实际工作,这种设计方法极大的避免了设计和脚本编码的重复,极大的实现了复用。**

Maven的核心概念

  1. POM

    这是Maven最重要的一个概念, pom是指project object Model。pom是一个xml,在maven2里为pom.xml。是maven工作的基础,在执行task或者goal时,maven会去项目根目录下读取pom.xml获得需要的配置信息

    这个POM,就是maven平台的领域对象。 Maven就是围绕这个POM领域对象构建起来的领域平台。

    pom文件中包含了项目的信息和maven build项目所需的配置信息,通常有项目信息(如版本、成员)、项目的依赖、插件和goal、build选项等等

    pom是可以继承的,通常对于一个大型的项目或是多个module的情况,子模块的pom需要指定父模块的pom

    pom文件中节点含义如下:

    project

    pom文件的顶级元素
    

    modelVersion

    所使用的object model版本,为了确保稳定的使用,这个元素是强制性的。
    除非maven开发者升级模板,否则不需要修改
    

    groupId

    是项目创建团体或组织的唯一标志符,通常是域名倒写,
    如groupId  org.apache.maven.plugins就是为所有maven插件预留的
    

    artifactId

    是项目artifact唯一的基地址名
    

    packaging

    artifact打包的方式,如jar、war、ear等等。默认为jar。
    这个不仅表示项目最终产生何种后缀的文件,也表示build过程使用什么样的lifecycle。
    

    version

    artifact的版本,通常能看见为类似0.0.1-SNAPSHOT,其中SNAPSHOT表示项目开发中,为开发版本
    

    name

    表示项目的展现名,在maven生成的文档中使用
    

    url

    表示项目的地址,在maven生成的文档中使用
    

    description

    表示项目的描述,在maven生成的文档中使用
    

    dependencies

    表示依赖,在子节点dependencies中添加具体依赖的groupId artifactId和version
    

    build

    表示build配置
    

    parent

    表示父pom
    

    groupId:artifactId:version唯一确定了一个artifact

  2. Artifact

    一个项目将要产生的文件,可以是jar文件,源文件,二进制文件,war文件,甚至是pom文件。每个artifact都由groupId:artifactId:version组成的标识符唯一识别。需要被使用(依赖)的artifact都要放在仓库

  3. Repositories

    Repositories是用来存储Artifact的。如果说我们的项目产生的Artifact是一个个小工具,那么Repositories就是一个仓库,里面有我们自己创建的工具,也可以储存别人造的工具,我们在项目中需要使用某种工具时,在pom中声明dependency,编译代码时就会根据dependency去下载工具(Artifact),供自己使用。

    对于自己的项目完成后可以通过mvn install命令将项目放到仓库(Repositories)中
    仓库分为本地仓库和远程仓库,远程仓库是指远程服务器上用于存储Artifact的仓库,本地仓库是指本机存储Artifact的仓库,对于windows机器本地仓库地址为系统用户的.m2/repository下面。

    对于需要的依赖,在pom中添加dependency即可,可以在maven的仓库中搜索:http://mvnrepository.com/

  4. Build(Lifecycle -> Phase -> Goal)

    Lifecycle(生命周期),是指一个项目build的过程。这是maven最高级别的的控制单元,它是一系列的phase组成,也就是说,一个生命周期,就是一个大任务的总称,不管它里面分成多少个子任务,反正就是运行一个lifecycle,就是交待了一个任务,运行完后,就得到了一个结果,中间的过程,是phase完成的,自己可以定义自己的lifecycle,包含自己想要的phase

    maven的Build Lifecycle分为三种,分别为default(处理项目的部署)、clean(处理项目的清理)、site(处理项目的文档生成)。他们都包含不同的lifecycle。

    可以理解为任务单元,lifecycle是总任务,phase就是总任务分出来的一个个子任务,但是这些子任务是被规格化的,它可以同时被多个lifecycle所包含,一个lifecycle可以包含任意个phase,phase的执行是按顺序的,一个phase可以绑定很多个goal,至少为一个,没有goal的phase是没有意义的

    下面重点介绍default Build Lifecycle几个重要的phase:

    validate

    验证项目是否正确以及必须的信息是否可用
    

    compile

    编译源代码
    

    test

    测试编译后的代码,即执行单元测试代码
    

    package

    打包编译后的代码,在target目录下生成package文件
    

    integration-test

    处理package以便需要时可以部署到集成测试环境
    

    verify

    检验package是否有效并且达到质量标准
    

    install

    安装package到本地仓库,方便本地其它项目使用
    

    deploy

    部署,拷贝最终的package到远程仓库和替他开发这或项目共享,在集成或发布环境完成
    

    以上的phase是有序的(注意实际两个相邻phase之间还有其他phase被省略,完整phase见lifecycle),下面一个phase的执行必须在上一个phase完成后

    若直接以某一个phase为goal,将先执行完它之前的phase,如mvn install
    将会先validate -> compile -> test -> package -> integration-test ->verify最后再执行install phase

    goal代表一个特定任务

    A goal represents a specific task (finer than a build phase) 
    which contributes to the building and managing of a project.
    

    mvn package表示打包的任务,通过上面的介绍我们知道,这个任务的执行会先执行package phase之前的phase

    mvn deploy表示部署的任务

    mven clean install则表示先执行clean的phase(包含其他子phase),再执行install的phase。

    mojo:

    lifecycle与phase与goal都是概念上的东西,mojo才是做具体事情的,
    可以简单理解mojo为goal的实现类,它继承于AbstractMojo,
    有一个execute方法,goal等的定义都是通过在mojo里定义一些
    注释的anotation来实现的,maven会在打包时,自动根据这些anotation
    生成一些xml文件,放在plugin的jar包里
    
  5. Archetype

    原型对于项目的作用就相当于模具对于工具的作用,我们想做一个锤子,将铁水倒入模具成型后,稍加修改就可以了。

    类似我们可以根据项目类型的需要使用不同的Archetype创建项目。通过Archetype我们可以快速标准的创建项目。利用Archetype创建完项目后都有标准的文件夹目录结构

    既然Archetype相当于模具,那么当然可以自己再造模具了啊,创建Archetype

    下面介绍利用maven自带的集中Archetype创建项目。创建项目的goal为mvn archetype:generate,并且指定archetypeArtifactId,其中archetypeArtifactId见maven自带的archetypeArtifactId

  6. Plugin

    maven的核心仅仅定义了抽象的生命周期,具体的任务是交由插件完成的,插件以独立的形式存在。
    对于插件本身,为了能够复用代码,它往往能够完成多个任务。如maven-dependency-plugin有十多个目标,每个目标对应了一个功能,如 dependency:analyze、 dependency:tree和dependency:list。这是一种通用的写法,冒号前面是插件前缀,后面是该插件的目标。

    maven的生命周期与插件相互绑定,用以完成实际的构建任务。具体而言,是生命周期的阶段与插件的目标相互绑定,已完成某个具体的构建任务。例如项目编译这一任务,它对应了default生命周期的compile阶段,而maven-compiler-plugin这一插件的compile目标能够完成该任务,因此将他们绑定。

    比如maven缺省的三个生命周期: clean, default, site和插件绑定如下:

    Clean

    clean   clean:clean
    

    Site

    site    site:site
    site-deploy     site:deploy
    

    Default

    process-resources   resources:resources
    compile     compiler:compile
    process-test-resources  resources:testResources
    test-compile    compiler:testCompile
    test    surefire:test
    package     ejb:ejb or ejb3:ejb3 or jar:jar or par:par or rar:rar or war:war
    install     install:install
    deploy  deploy:deploy
    

    用户还能够自己选择奖某个插件目标绑定到生命周期的某个阶段以执行更多更特色的任务。

    比如:

            <plugin>  
                <groupId>org.apache.maven.plugins</groupId>  
                <artifactId>maven-dependency-plugin</artifactId>  
                <version>2.1</version>  
                <executions>  
                    <execution>  
                        <id>copy</id>  
                        <phase>install</phase>  
                        <goals>  
                            <goal>copy-dependencies</goal>  
                        </goals>  
                        <configuration>  
                            <outputDirectory>lib</outputDirectory>  
                        </configuration>  
                    </execution>  
                </executions>  
            </plugin>  
    

    定义了一个id为copy的任务,利用插件maven-dependency-plugin的copy-dependencies目标绑定到default生命周期的install阶段,来实现项目依赖的jar包的自动复制。

    当插件目标被绑定到不同的生命周期阶段时候,其执行顺序会有生命周期阶段的先后顺序决定的。如果多个目标被绑定到同一个阶段,他们的执行顺序是由插件声明的先后顺序决定目标的执行顺序。

  7. profile

    一个优秀的构建系统必须足够灵活,应该能够让项目在不同的环境下都能成功构建。maven为了支持构建的灵活性,内置了三大特性,即:属性、profile和资源过滤。

    profile定义了一系列的profile变量,在具体构建时可用使用其中的某个profile去变量替换资源文件。

Maven设计特点

在上面的介绍里我们花了很长的篇幅来介绍maven的模型,概念,功能,和运作方式。大家也跟了解**maven是基于project这个领域对象模型上,以项目周期管理为目标而构建的领域平台。**

  1. 设计了领域模型,所有的功能围绕项目Project这个领域模型构建

  2. 设计了领域模型的生命周期和执行方式(lifecycle-phase-goal)

  3. 设计了项目的原型模式(architype)

  4. 设计了可扩展的插件体系(plugin-mojo)

  5. 设计了依赖管理(dependencies)

  6. 设计了动态配置机制(profile)

  7. 设计了artiface仓库模型(repositories)

从这7个设计点可以看出,maven这个平台设计得很清晰,对需要解决的问题(项目管理构建)设计了一系列的概念, 功能,流程,方便maven的使用者明确的掌握,同时又可以针对自己的个性化需要去定制扩展平台的功能。

构建maven式领域平台

前面我们都是在介绍maven本身和他的设计特点。 现在我们要发散思考,这种设计在我们用来做自己业务系统的领域平台时有什么可以借鉴。

**Maven是基于领域模型驱动设计的平台,围绕这个业务模型,从他的起始状态到结束状态有一个明显的生命周期概念, 在这个生命周期里,不同的功能点独立实现同时又被复用形成多个顺序执行的任务单元推动周期的执行。 **

在我们的业务系统中也有很多类似的需要。 比如下面我们用招商和交易下单为例。

招商平台和Maven平台类比

  1. 什么是招商

    每年大促前期最重要的准备工作就是招商,招商就是淘宝小二创建了一个活动项目,设计这个活动的玩法, 然后吸引一些商家带着他们商品参加这个活动,然后小二通过各种资质验证保证报名商家的资质,并通过各种条件在这些商家中选择出最后参加活动的结果。然后这个项目活动在参与者,玩法等确定下,去执行一些必要的动作,保障这个活动项目在活动期间能够按照设计的完成。

  2. 招商的领域模型(domain)

    招商中最重要的领域模型是活动,我们也可以更规范的成为活动项目(project),每一次小二开始一个招商活动,其实就是设计一个招商活动项目。项目里需要明确项目的参与者,项目的时间(报名期,审核期,活动期),项目的玩法,项目的产出和需要执行的任务。

  3. 活动项目的生命周期(lifecycle)

    很直观,我们就可以确定活动项目是有一个生命周期的。从小二创建活动项目开始到活动结束,基本会经历一下周期,创建->报名->审核->启动->运行->结束->收尾。

    每个周期可以分多个阶段,每个阶段都有多个目标需要被执行。这些任务可以被灵活复用。
    如何设计这些周期,阶段和目标对招商平台化是否成功有决定性作用。

  4. 活动项目的原型模板(architype)

    每次小二设计一个活动项目,从资质,玩法,到运作方式等都需要做很多配置,管理。资深运营小二如何把他们的经验沉淀起来。避免下次类似的活动项目必须从头开始,新手小二也很难设计出一个成功的活动。这些就需要把这些活动按照一定的模式沉淀成原型(项目的模板),方便下一次即使是新手也可以快速的构建高效的活动项目。那么招商平台就也需要设计类似maven 原型类似的功能。

  5. 可扩展的插件体系(plugin-mojo)

    招商可以说是根据业务方需求,不停的响应提供新的功能支持新的需求等。当新的需求来的时候,我们需要分析出平台不足或者需要定制的功能点,然后以插件扩展的方式完成开发,同时能把这些功能很好的注册沉淀到平台,平台的功.能随着业务的发展越来越强大。比如支持更多的资质校验,支持更多的算法模型,对已有流程如何进行定制扩展,加入新的流程点等等。都需要平台提供一个类maven的可扩展的插件体系。

  6. 依赖管理(dependencies)

    招商活动会有很多的依赖,比如IC,UIC,报名的商家和商品资源,搜索算法等等。如何把这些依赖类似maven一样管理起来,对招商活动项目的运作和监控也就更加直观。

  7. 动态配置机制(profile)

    很明显,这个机制对招商活动项目也很有用处,比如每次活动对商品的打标,活动时间之类都需要类似的功能机制去保障。方便小二的使用调整。比如小二可以预先准备一些配置,然后根据实际情况,切换不同的配置。

  8. artiface仓库模型(repositories)

    活动项目依赖的各种插件实现, 活动结束后生成的案例资源,都可以以案例库的方式存储起来。方便更进一步的知识积累和业务扩展。

这些只是对招商这个复杂系统的初步想法,具体招商如何设计模型,生命周期等都需要结合目前招商的功能,按照这种思路,我相信我们的招商平台会有一个很好的架构,以后也许我们可以给小二提供类似maven命令的方式来构建活动了,:)

mvn create 创建活动
mvn enroll 报名
mvn review 审核
mvn start 启动
mvn close 结束
mvn clear 扫尾

招商平台化会包括以下功能:

  1. 活动项目对象模型

  2. 活动项目构建引擎

  3. 开放平台

  4. 原型管理

  5. 业务识别

  6. ...

通过这些我们打造一个强大的招商平台。

交易下单平台(Buy)和Maven平台类比

另一个很类似的就是buy下单了,基于订单模型,下单是个典型的生命周期,也很适合用maven的思路来设计。 大家也可以按照类似的思路分析下。 此处省略 1000字,:)。

mvn buy
mvn promotion
mvn ...
mvn order

总结

在工具软件里,有很多很好的设计,这些设计对我们做业务系统是个很好的参考。 比如eclipse, maven(还可以关注gradle,这个设计更好),我们可以用这些平台系统来作为我们平台化的参考类比设计,开拓我们的思路。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
如何设置阿里云服务器安全组?阿里云安全组规则详细解说
阿里云安全组设置详细图文教程(收藏起来) 阿里云服务器安全组设置规则分享,阿里云服务器安全组如何放行端口设置教程。阿里云会要求客户设置安全组,如果不设置,阿里云会指定默认的安全组。那么,这个安全组是什么呢?顾名思义,就是为了服务器安全设置的。安全组其实就是一个虚拟的防火墙,可以让用户从端口、IP的维度来筛选对应服务器的访问者,从而形成一个云上的安全域。
19808 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,阿里云优惠总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系.
29172 0
阿里云服务器安全组设置内网互通的方法
虽然0.0.0.0/0使用非常方便,但是发现很多同学使用它来做内网互通,这是有安全风险的,实例有可能会在经典网络被内网IP访问到。下面介绍一下四种安全的内网互联设置方法。 购买前请先:领取阿里云幸运券,有很多优惠,可到下文中领取。
22539 0
阿里云服务器ECS登录用户名是什么?系统不同默认账号也不同
阿里云服务器Windows系统默认用户名administrator,Linux镜像服务器用户名root
16455 0
阿里云服务器端口号设置
阿里云服务器初级使用者可能面临的问题之一. 使用tomcat或者其他服务器软件设置端口号后,比如 一些不是默认的, mysql的 3306, mssql的1433,有时候打不开网页, 原因是没有在ecs安全组去设置这个端口号. 解决: 点击ecs下网络和安全下的安全组 在弹出的安全组中,如果没有就新建安全组,然后点击配置规则 最后如上图点击添加...或快速创建.   have fun!  将编程看作是一门艺术,而不单单是个技术。
20700 0
腾讯云服务器 设置ngxin + fastdfs +tomcat 开机自启动
在tomcat中新建一个可以启动的 .sh 脚本文件 /usr/local/tomcat7/bin/ export JAVA_HOME=/usr/local/java/jdk7 export PATH=$JAVA_HOME/bin/:$PATH export CLASSPATH=.
14900 0
阿里云服务器怎么设置密码?怎么停机?怎么重启服务器?
如果在创建实例时没有设置密码,或者密码丢失,您可以在控制台上重新设置实例的登录密码。本文仅描述如何在 ECS 管理控制台上修改实例登录密码。
23581 0
+关注
uyang
青霖,来自淘宝技术部
10
文章
10
问答
文章排行榜
最热
最新
相关电子书
更多
JS零基础入门教程(上册)
立即下载
性能优化方法论
立即下载
手把手学习日志服务SLS,云启实验室实战指南
立即下载