毋庸置疑,Spring Boot在众多从事Java微服务开发的程序员群体中是一个很特别的存在。说它特别是因为它确实简化了基于Spring技术栈的应用/微服务开发过程,使得我们能够很快速地就搭建起一个应用的脚手架并在其上进行项目的开发,再也不用像以前那样使用大量的XML或是注解了,应用在这样的约定优于配置的前提下可以以最快的速度创建出来。
Spring Boot从这一点来说极大解放了开发者,使得开发者从之前繁琐的配置中解脱出来,转而专注于应用的业务逻辑开发。这样,我们的系统的开发周期就会大大缩短,交付周期也越来越频繁了,这同样也是Spring Boot为我们广大开发者所带来的巨大好处。我们可以尽情享受这样一个优秀框架在方方面面所带来的功能,甚至很多功能都可以做到开箱即用,只需在POM或是build.gradle中简单配置一下即可,相比于之前的Spring MVC等传统的Web开发模式来说简化了太多太多。
总的来说,Spring Boot在如下几个方面为我们带来了巨大的效能提升:
- 约定优于配置。按照Spring Boot的方式进行简单的配置后,功能就可以直接使用了。
- 自动装配。Spring Boot在启动时会自动探测类路径下的各种类型,实现类型的自动装配,无需开发者再通过XML或是注解进行显式的类型装配了,这一点要拜@EnableAutoConfiguration注解或是更为全面的@SpringBootApplication注解所赐。
- 内嵌各种Servlet容器。Spring Boot内嵌了Tomcat、Jetty与Undertow等Servlet容器,使得我们可以像开发普通的Java应用那样直接通过main方法来启动容器,甚至可以直接通过jar包而非war包的形式就能够实现快速部署,不必再依赖于外部的Servlet容器。
- yml配置的支持。yml或是yaml的全称是YAML Ain't Markup Language的简称(有意思的是,当初在开发这门语言时,其简称实际上是Yet Another Markup Language),新的简称采取了递归的方式。这种新的语言可以看作是传统的properties配置文件的一种有益补充,它通过缩进的方式来表示层次化的配置项,相比于传统的properties属性文件来说,其层次感会更好一些;当然,顺便也可以让我们少敲一些字母。
- 提供了各种starter便于功能的开箱即用。围绕着Spring Boot生态圈目前已经涌现出了不计其数的starter,这样我们只需将相应的starter配置项引入到项目中即可很方便地使用对应的功能。
- 提供了各种度量。Spring Boot提供了各种度量属性,便于我们查看当前项目的运行情况以及系统使用情况。
Spring Boot所提供的功能非常之多,上面不过是列举出了它诸多功能的几个方面而已。
不过,这篇文章的主旨却并不在Spring Boot所提供的如此之多的功能特性上,而是从一个开发者视角来分析学习和使用Spring Boot时我们该如何去做;换句话说,我认为正确的学习路径和曲线应该是怎样的。
下面是我经过一段时间的仔细观察,发现很多开发者在学习和使用Spring Boot时所存在的严重误区:
- Spring Boot非常方便,简单,拿来就用。这是Spring Boot自身的优良特性给开发人员所带来的最大的一个误解。诚然,在我们刚开始上手Spring Boot时,只需要短短10分钟左右的时间就能让一个Web应用运行起来,这只要按照Spring Boot官方网站的示例跟着做下来即可。当这个简单的示例应用成功运行起来后,你会发现自己几乎没写什么代码,配置更是只是加上了几个注解就行了。在这样的前提下,应用竟然就能正常运行起来了,神不神奇,牛不牛逼。
于是,你认为Spring Boot果然是神器啊,果然是简单啊,果然是方便啊。在这个示例的基础上再增加点功能貌似也是比较轻松的,再加一个url mapping,嚯,可以访问到了,嘎嘎。
所以,你得出了这样一个结论:Spring Boot从入门到精通只需要一天时间即可。
骚年,你咋这么幼稚不成熟呢?
Spring Boot的本质是什么?Spring Boot官网明确表示自己不提供任何新的特性与功能,只是将之前传统的基于Spring的开发进行了简化,便于开发者上手。
看到了么,这里的要点是什么?
Spring复杂么?当然复杂了,那为什么我们用Spring Boot进行开发时却感受不到这种复杂性呢?
答案当然是Spring Boot将这种复杂性封装起来了。一个框架或是系统如果是复杂的,那么这种复杂性就会存在两种地方:
将复杂性全部封装起来,对使用者暴露简单的使用接口。
将复杂性暴露给使用者。
复杂系统无它,上述两点而已。
对于Spring Boot来说,显然它采取的是第一种策略,即将复杂性封装起来,向使用者暴露简单的接口,让开发者能够快速上手。
但显然,我们所开发的系统不可能是那么简单的,它或多或少地需要使用很多其他很多技术,当这些技术被集成到Spring Boot中时,很多问题就开始暴露出来了,这时的你如果没有扎实的基础,就会陷入遇到一个问题就到处搜结果的窘境,结果造成一天下来疲于搜索答案。经过了一段时间,你可能会反问自己:这是我要的Spring Boot么?怎么感觉还不如使用传统的Spring MVC开发速度快呢?
当我们使用传统的开发模式时,大多数内容都是我们自己来设置的;在这种情况下,系统出现了问题后,我们能够比较快地定位到问题所在;然而,在Spring Boot中,因为一切都是自动装配的,因此一旦出现问题,定位问题就是一个非常耗时耗力的事情。
- 学习Spring Boot不需要对Spring有太深入的了解和学习。一般来说,但凡有这种想法的人大多数都是没有接触过传统的Spring MVC或是Spring开发的年轻程序员,他们一上来使用的就是Spring Boot框架,开发了几个项目后就得出了这样的结论。
在我们使用基于Spring技术栈的框架时,无论使用的框架是什么,Spring永远都是基础,永远都处于根基的位置。没有对Spring的深入理解和学习,你使用构建于其上的任何框架都只不过是水中月,镜中花而已,经不起任何推敲。也许你对框架的API、类、方法都比较了解,知道怎么用,但你有没有想过,这些东西对于经验丰富的Spring开发者来说,掌握起来速度其实是很快的,而且更加扎实。毕竟,Spring是这一切的根源,对于Spring有了深入的理解与认知后,再来反观构建于其上的各种应用层框架,你会有完全不同的感受的。
Spring Boot的配置方式简单,更加优越。我相信,这也是很多开发者在使用Spring Boot时所得出的一个结论。但是,我想问题的是,YAML真的就比properties强大很多么(当然,Spring Boot对于这两种方式都是支持的)。如果你的配置项很多,而且都放到了application.yml中时(特别地,将各种profile配置也都放到了这里),那你再来看看你的yml文件,你还会有良好的心情么?
Spring Boot项目一旦出现问题,特别是那种自动配置出现问题,或是同一个类型有几个对应项时,排查起来不是那么容易的事情,尤其在项目规模比较庞大时更是如此。这就需要你对Spring Boot的底层有良好的掌握与认知才能较快地找出问题所在。
配置的加载。我相信很多做Spring Boot开发的程序员们都读过网上关于Spring Boot配置信息加载优先级的文章。姑且不论这些文章的正确与否,你是否真正理解了配置信息优先级问题,Spring Boot是如何处理配置信息的加载优先级的。
对Spring Boot的误解太多,这里面仅列出上述五条。
那么,问题到底出在哪里呢?显然,问题的根源不在Spring Boot,那就在你自身喽。
还是那句话,Spring Boot绝不是一个可以速成的框架,我们虽然可以快速上手Spring Boot,用它做一些简单的示例或是项目,但是当项目规模变大时,如果没有良好的基础,你是无法很好地驾驭它的;Spring Boot绝非一个简单的框架,它是诸多模式、思想、经验的集大成者。但,虽然它将复杂性隐藏了起来,我们在实际开发中依然会遇到形形色色的问题,这时的你若是具备优秀的Spring和Spring Boot基础,那么问题的解决就是一个快速提升的过程,否则有些问题不是简单搜索一下网上资料就能搞得定的。
如果你做过大规模的Spring Boot项目,我相信你会认同我上述的观点的。
无它,唯手熟尔。
Spring Boot是一个极为优秀的框架,优秀的框架需要我们也能配得上,这就需要我们首先将自己变成一个优秀的Spring与Spring Boot开发者,探究本源,这样才能得心应手,行走在技术的前沿。
作者简介:张龙,系统架构师,资深培训讲师,圣思园教育创办者,译者。译有《复杂性思考》、《iPhone游戏开发》、《精通lambda表达式:Java多核编程》、《设计原本》、《Python并行编程手册》等20余本译作;喜好研究技术,对系统底层有浓厚的兴趣。