在讲解基础知识的过程中,我们也要动手去写。而Java发展到现在,可以帮助我们写程序,构建,发布的工具有一大堆。今天就来讨论一下构建工具。在开始之前,我们先讲点别的。

如何学习琳琅满目的框架和工具

学Java的新人,最头疼的事情,莫过于工具太多,挑花了眼。不管你要做什么,几乎都要面临各种各样的选择。我是应该选hibernate呢?还是mybatis。我新建一个工程,要不要加上spring?mvc, tx都是什么?tomcat,jetty是什么?网络编程要不要用netty?要在服务端布署多个机器,用akka行不行?DMQ呢?protobuf是什么鬼?类似的问题还有很多。

如果利用搜索引擎,想去看看这些工具分别是干嘛的,会发现,搜索结果五花八门,说什么的都有,甚至有些说法都相互矛盾。造成这些乱象的原因,一是Java的应用过于广泛,在不同的软件体系中都能看到Java的身影,而不同的需求,会使用不同的工具,甚至是同样的工具,在不同的环境下,都会有不同的用法。二是,Java的流行已经有很长时间了,随着时间的推移,肯定会有很多工具没有跟上历史的潮流而慢慢被淘汰。比如J2EE现在的市场占有率只有不足5%。再比如java swing的图形界面编程,现在几乎没有公司再使用swing进行图形界面编程了,最早,互联网公司就几乎没有采用过swing的方案。swing只在某些企业级软件里发挥作用,而随着HTML5的兴起,越来越多的软件公司也把自己的界面搬到web前端,现在的html5对2d, 3d都有非常好的支持,而一套简洁的CSS就能定制出漂亮的界面。所以swing被html5挤出历史进程实属正常。再比如JSF,JavaFX等等,也算是出师未捷身先死。有用的,没用的一堆堆地都堆到新手面前,新手的感觉肯定就是“那叫一个乱”啊。

说到这里,吐槽一下,某些培训机构和出版机构。为了凑篇幅,还会把一些已经不常用的技术加上,这就给新手们,尤其是自学的新手们带来误导,以为这些东西很重要。例如《Java核心技术》这本书的第一卷里,还为swing准备了大段的篇幅,甚至还有awt,而这些东西早就不应该被列入学习计划了。这一点《Java编程思想》会好一点,在第4版里,图形界面编程已经压缩到最后一章了,做为参考提醒一下读者,Java里还有这么个玩意。

关于这些框架,工具的学习,我这里有一个建议:什么都别学,从基础开始,把根基搞扎实了。然后自己动手做工程,遇到问题了,再去学习会更好。我觉得一个好的老师,不是手把手地把知识教给你,而是能够指出问题的所在。我举一个例子。我之前指导过一个师弟学习Java,我让他自己用socket写一个web server ,他使用了一个线程一个连接的原始的线程方案,并且使用本机测试,开了十来个客户端,觉得还不错。我就告诉他,你这样的测试是不对的,你要去找一个client端的benchmark,或者自己写个工具,创建成百上千个连接,然后再看看你的web server的表现如何。后来,他发现,当创建几百个连接以后,服务端几乎就跑不动了。然后,我就提醒他,可以考虑一下,业界有哪些解决方案。这时候,他找到了nio,netty, 线程池等等方案。然后自己去重构,重构过程中,发现逻辑和页面合在一起,很难处理,又引入了spring mvc,为了操作数据库,又引入了hibernate等等。

回顾他学习的过程可以发现,对于工具和框架,被动地学习会比主动地学习效果好。到了不得不学的时候再去学习,有具体的场景,学起来必然事半功倍。我再举一个例子,上次在北京和朋友一起吃饭,他抱怨说Java不好招。我说,北京那么多培训班,新人一把一把地,不是随便招吗?他就讲了自己的面试经历。有一个小伙子,简历上写了熟悉servlet, spring,ibatis等框架。他就和这个小伙子聊怎么用这些框架,小伙子答的还可以。然后他就问到了http协议和Java中的Proxy(这是实现Spring的核心机制)以及reflection,小伙子就答不上来了。这就有点舍本逐末了,且不说,是不是所有公司都会使用spring,就算spring是标准配置,被写到Java语言标准中去,那也不能基础太薄弱了,出了诡异BUG,都不知道怎么查。框架这个东西,遇到问题再去学吧,如果你跟着框架走,三天两头有新的东西出来,你只能疲于奔命。今天出个rabbitmq,你要学,明天出个kafka,你还要学,没准哪天又出来个什么样的新DMQ,你还是得学。这学到什么时候是个头了。

回到今天的主题,我们讨论三个构建工程用的工具。

构建工具

我们要写一个Java程序,一般的步骤也就是编译,测试,打包。这个构建的过程,如果文件比较少,我们可以手动使用java, javac, jar命令去做这些事情。但当工程越来越大,文件越来越多,这个事情就不是那么地令人开心了。因为这些命令往往都是很机械的操作。但是我们可以把机械的东西交给机器去做。

在linux上,有一个工具叫make。我们可以通过编写Makefile来执行工程的构建。windows上相应的工具是nmake。这个工具写起来比较罗嗦,所以从早期,Java的构建就没有选择它,而是新建了一个叫做ant的工具。ant的思想和makefile比较像。定义一个任务,规定它的依赖,然后就可以通过ant来执行这个任务了。我们通过例子看一下。下面列出一个ant工具所使用的build.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<project name="HelloWorld" default="run" basedir=".">
<property name="src" value="src"/>
<property name="dest" value="classes"/>
<property name="jarfile" value="hello.jar"/>
<target name="init">  <mkdir dir="${dest}"/>
</target>
<target name="compile" depends="init">  <javac srcdir="${src}" destdir="${dest}"/>
</target>
<target name="build" depends="compile">  <jar jarfile="${jarfile}" basedir="${dest}"/>
</target>
<target name="test" depends="build">  <java classname="test.ant.HelloWorld" classpath="${hello_jar}"/>
</target>
<target name="clean">  <delete dir="${dest}" />  <delete file="${hello_jar}" />
</target>
</project>  

可以看到ant的构建脚本还是比较清楚的。ant定义了五个任务,init, compile, build, test, clean。每个任务做什么都定义清楚了。打包之前要先编译,所以通过depends来指定依赖的路径。如果在命令行里执行ant build,那就会先执行compile,而compile又依赖于init,所以就会先执行init。看起来很合理,对吧?有了这个东西以后,我们只要一条命令:

ant test

就可以执行编程,打包,测试了。为开发者带来了很大的便利。

但是ant有一个很致命的缺陷,那就是没办法管理依赖。我们一个工程,要使用很多第三方工具,不同的工具,不同的版本。每次打包都要自己手动去把正确的版本拷到lib下面去,不用说,这个工作既枯燥还特别容易出错。为了解决这个问题,maven闪亮登场。

maven最核心的改进就在于提出仓库这个概念。我可以把所有依赖的包,都放到仓库里去,在我的工程管理文件里,标明我需要什么什么包,什么什么版本。在构建的时候,maven就自动帮我把这些包打到我的包里来了。我们再也不用操心着自己去管理几十上百个jar文件了。

这了达到这个目标,maven提出,要给每个包都标上坐标,这样,便于在仓库里进行查找。所以,使用maven构建和发布的包都会按照这个约定定义自己的坐标,例如:

<?xml version="1.0" encoding="utf-8"?>

这样,我就定义了我自己的包的坐标是cn.hinus.recruit:Example:0.1.0-SNAPSHOT,而我的工程要依赖junit:junit:4.10。那么maven就会自动去帮我把junit打包进来。如果我本地没有junit,maven还会帮我去网上下载。下载的地方就是远程仓库,我们可以通过repository标签来指定远程仓库。

maven里抛弃了ant中通过target定义任务的做法,而是引入了生命周期的概念。这个问题要讲下去,就是一个大的话题了。我们暂时放一下。因为我们要看今天的最终BOSS,gradle

Gradle

maven已经很好了,可以满足绝大多数工程的构建。那为什么我们还需要新的构建工具呢?第一,maven是使用xml进行配置的,语法不简洁。第二,最关键的,maven在约定优于配置这条路上走太远了。就是说,maven不鼓励你自己定义任务,它要求用户在maven的生命周期中使用插件的方式去工作。这有点像设计模式中的模板方法模式。说通俗一点,就是我使用maven的话,想灵活地定义自己的任务是不行的。基于这个原因,gradle做了很多改进。

gradle并不是另起炉灶,它充分地使用了maven的现有资源。继承了maven中仓库,坐标,依赖这些核心概念。文件的布局也和maven相同。但同时,它又继承了ant中target的概念,我们又可以重新定义自己的任务了。(gradle中叫做task)

我们来体验一下,新建一个空目录,在命令行,执行

gradle 

可以看到新创建了一个工程,工程根目录下,有这几项:

build.gradle  gradle  settings.gradle  src

我们看一下,build.gradle的内容:

// Apply the java plugin to add support for Java

内容很简单,引入了java插件,指定仓库,指定依赖。可以看到依赖的设定相比起xml的写法,变得大大简化了。

使用gradle,任务又变成了核心概念了。我们就来体验一下任务。

在build.gradle里添加这样的任务:

task hello << { println 'welcome to gradle';
}

然后在命令行执行

gradle -q hello

就可以看见打印一行"welcome to gradle"。在使用maven构建的时候,如果想临时对某一个构建任务加一点log,会是个非常困难的事情 。但在gradle里,就变得非常简单,因为gradle的背后其实是groovy这个编程语言在起作用。为了验证这一点,我们再改一下:

task 

然后执行gradle -q hello,就可以看到连续打印了三行。使用脚本语言进行构建,这几乎给了我们任何的能力,我们可以在构建的时候做任何的事情,甚至你可以直接让gradle帮你做表达式求值 :)

导入到 IDE

在Java的开发中,我们不可能脱离集成开发环境(Integrated Develop Environment)。因为IDE提供了代码补全和方便的代码跳转,这是普通的文本编辑软件(比如vim)很难做到的。所以我们还是要通过ide来进行代码开发。

以前在ide里使用spring的时候,我们要手动下载spring的包,如果spring依赖了其他的第三方的库,我们还要去下载那个库并且添加到IDE中去。现在,我们就不必再这样做了。只需要在build.gradle里定义好依赖,然后更新它,IDE就可以自动帮我们把包导进来。

例如,我要在新建的工程里使用spring,只需要在build.gradle里添加一行:

然后,在gradle窗口里,点击更新:

然后,intellij就自动把spring所依赖的所有包都下载下来了。

非常方便。

好了,今天的课程就到这里了。作业:

使用gradle新建一个工程,并把它导入到你喜欢的IDE中去。添加spring依赖,并更新,观察一下,gradle的工作方式。

小密圈《进击的Java新人》中,有更详细的内容,以及我已经建好的一个工程。已经加入小密圈的同学请去git上clone下来,我们接下来的课程会在这个工程上写代码咯。知乎专栏只负责讲解知识,不负责指导动手。

上一节:进制习题课

下一节:Java中的设计模式:适配与装饰

课程目录:总目录

kafka maven没有下载_构建工具的进化:ant, maven, gradle相关推荐

  1. 前端构建工具_构建工具

    前端构建工具 深度JavaScript (Deep JavaScript) Choosing a development tool based on its popularity isn't a ba ...

  2. maven 打包编译_您是否真的想加快Maven的编译/打包速度? 那么takari生命周期插件就是答案。...

    maven 打包编译 像你们中的许多人一样,我正在使用多模块Maven项目 . 与现有的许多系统相比,它不是一个巨大的系统,它具有15个模块,3种不同的耳朵部署,带有属性文件的大量参数化以及大约10万 ...

  3. mysql maven 自动生成_【图文经典版】maven自动生成dao层

    第一步:POM文件 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/mav ...

  4. 新一代的构建工具Gradle

    Gradle是什么? 一个开源的项目自动化构建工具, 建立在apache ant和maven的基础上, 并引入基于Groovy的特定领域语言(DSL), 不再使用xml形式管理构建脚本. 构建工具的发 ...

  5. 【Groovy】Gradle 构建工具 ( 自动下载并配置构建环境 | 提供 API 扩展与开发工具集成 | 内置 Maven 和 Ivy 依赖管理 | 使用 Groovy 编写构建脚本 )

    文章目录 一.Gradle 自动下载并配置构建环境 二.Gradle 提供 API 扩展与开发工具集成 三.Gradle 内置 Maven 和 Ivy 依赖管理 四.Gradle 使用 Groovy ...

  6. 下一代构建工具 Gradle ,比 Maven 强在哪里!

    作者 :乐百川 本文:toutiao.com/i6824937779193971207 相信使用Java的同学都用过Maven,这是一个非常经典好用的项目构建工具.但是如果你经常使用Maven,可能会 ...

  7. 更快的Maven构建工具mvnd和Gradle哪个性能更好?

    作者 | 磊哥 来源 | Java中文社群(ID:javacn666) 转载请联系授权(微信ID:GG_Stone) Maven 作为经典的项目构建工具相信很多人已经用很久了,但如果体验过 Gradl ...

  8. 全网最全、最新Maven构建工具核心知识,这篇文章包你这辈子也忘不掉Maven!!

    作者:Java学术趴 仓库:Github.Gitee 博客:CSDN.掘金.InfoQ.云+社区 公众号:Java学术趴 特别声明:原创不易,未经授权不得转载或抄袭,如需转载可联系小编授权 版权声明: ...

  9. aliyun gradle 代理_gradle:现代高效的java构建工具

    相信使用Java的同学都用过Maven,这是一个非常经典好用的项目构建工具.但是如果你经常使用Maven,可能会发现Maven有一些地方用的让人不太舒服: 一来Maven的配置文件是XML格式的,假如 ...

最新文章

  1. 快速选择思维导图软件,就是这么任性
  2. php xml写入数据库中,PHP读取xml并写入数据库示例
  3. 记一次php手工注入(mysql)
  4. Jfinal 对象列表返回前台json数据
  5. C++中const迭代器 和 const_iterator的区别
  6. SecureCRT安装(5)
  7. 百度之星 度度熊的午饭时光
  8. 《回话的技术》读后感
  9. 微信企业转账到银行卡
  10. 如何查看计算机硬盘的软件内存条,内存检测工具,内存检测软件 - 内存条检测工具就用金山卫士 - 安全专题...
  11. 弘辽科技:淘宝新店扶持是人人享有的权益吗?
  12. photoshop 重复上一次变换操作 ctrl+shift+alt+t
  13. 揣着一口袋的阳光满载而归--爱摸鱼的美工(13)
  14. 2020年6月六级真题翻译:青藏铁路
  15. 对于程序员来说养成规范的打字真的很重要
  16. 动力电池罗生门:“无钴”的一张大网
  17. 自定制emoji替换系统的emoji键盘
  18. db2嵌套查询效率_提高DB2 查询性能的常用方法
  19. 敏捷方法 - 敏捷的理念
  20. 艺术的背后还有纪律——采访印度NIIT CEO有感

热门文章

  1. elementui可编辑单元格_关于遥感解译点室内解译编号的读取编辑方法
  2. 知乎热议:嵌入式开发中C++好用吗?
  3. 牛人自制电灯泡,20000W,结果“亮”了
  4. HDLBits答案(5)_Generate实例化模块
  5. VHDL交通灯控制器的设计
  6. mysql 设计两个主键都不可重复_18个MySQL面试题剖析(答案解析),听说身为程序员的你还没掌握...
  7. python开发笔记软件_图解Python编程神器Jupyter Notebook
  8. 微信lbs开发 php,【LBS】基于地理位置的搜索之微信 附近的人 简单实现
  9. python将小时数换成分钟_如何在Python中将datetime.timedelta转换为分钟、小时?
  10. magento网站建设_外贸网站建设指南,告诉你建站系统怎么选择