SpringBoot颠覆JavaEE的开发模式
一、前言
在脚本语言和敏捷开发大行其道的时代,JavaEE的开发显得尤为笨重,让人误解JavaEE开发就应该如此。Spring在提升JavaEE开发效率的脚步上从未停止过,而Spring Boot的推出是具有天赋和划时代意义的[1]。本文介绍了 SpringBoot和分析其与JavaEE开发体系的不同。分析以SpringBoot为核心的开发框架组成。最后分析部署、测试、监控和管理生产环境等问题。
二、主题
1. SpringBoot 与传统JavaEE项目开发模式比较。
JavaWeb应用开发从最早的Servlet技术开始已经经历了很多变化,在这段历史中产生了独立的一整套的生态系统和大量的开源项目[2]。EJB2.0改变了很多,但也还是保留了权威、官方和学术化的整体风格。在这个时候Spring等大批轻量级框架开始产生,发展到今天已经和JavaEE的开发模式形成有明显区别的一派,真正让我们看到开源社区改变JavaEE的应该是JAP,它的标准明显倾向于Hibernate。Java被 Oracle收购后对JavaEE不断发展但开发模式没有很大的发展。SpringBoot是在Spring的大框架下,离不开两项关键技术依赖注入和面向切面编程AOP。在 JDK5 引入的Annotation出现 后 Spring大量采用这种配置方式,但之前都是采用配置xml文件的形式。xml文件在webservice流行的时期被推崇的很高。开发人员渐渐发现xml文件越来越多,书写困难(可以对比YAML文件的书写),调试困难等等[3]。所以 Spring当初被人的批评很多都是因为xml配置过多。而 Spring Boot的改变不是仅仅采用了更好的配置文件格式那么简单。SpringBoot是采用了最初在Maven中看到的“约定大于配置”(Convention over configuration)的思想[4],也叫惯例优先原则。简单地解释就是绝大多数配置信息按约定采用缺省配制,用户需要的个性配置采用properties文件或yaml文件的格式写在统一的文 件中。其他在开发中的配置信息要么采用Annotation要么采用配置类形式。也就是说 SpringBoot可以达到免xml文件配置。这点区别于传统项目开发的特点也是给开发效能提升带来巨大效果的。
Spring Boot的运行方式是main方法。另外这个项目是Javaweb项目,它必然需要web容器,但这不是war包形式部署。实际上SpringBoot 改变了传统开发模式,将其开发的javaweb项目内部内嵌了一个Tomcat,而关键是最终的打包形式是一个包含了所有项目文件和内嵌、web容器的jar包。这个jar包的打包形式为将来部署到Docker上提供了良好的条件,这个后面还会提到 SpringBoot使Javaweb项目开发变得轻松很多[5],当然它的贡献也不止以上这些,当项目真正采用它来开发一般不会再退回原来的开发方式了。
2. SpringBoot应用系统开发模板架构设计从前台到后台的顺序进行分析。
从页面来看,现在的主流已经淘汰了jsp技术。前台常使用模板引擎,主要有 FreeMarker,它是一个用Java语言编写的模板引擎,基于模板来生成文本输出。还有Thymeleaf,它和FreeMarker的原理类似,可以达到页面图形设计和应用逻辑的分离。但SpringBoot 推荐使用Thymeleaf正原因首先是它可以和SpringMVC很好结合,其次和其他模板引擎相比它的模板可以直接用浏览器正确显示,这也称为自然的模板技术。但其使用的DOM解析所以不适合处理大XML文件。在前端开发还常用到BootStrap、 AngularJS、JQuery等。接下来在浏览器数据传输上采用Json 的格式RESTfu1传输。在数据到达服务器后接受请求的是 SpringMVC框架,这个框架已经取代struts2成为控制层绝对的主流了。到持久层框架现在的主流技术有Hibernate、Mybatis、JPA各有优缺点不再赘述。SpringBoot推荐使用Spring Data+JPA的方式[6],当然引擎常用Hibernate,数据库使用MySQL开发工具推荐用IntelliJ IDEA。
3. SpringBoot部署和测试带来的变革。
SpringBoot项目能够很好地部署于Docker类的虚拟容器中,Docker由2013年DotCloud公司发起,开源后快速发展。已经形成以Docker为中心的生态体系。Docker加入了 Linux基金会,遵循 Apache2.0协议。Docker的受欢迎程度很高,应用该项技术的大型互联网公司几乎占据主流市场的三分之一以上。SpringBoot也针对Docker技术做了很多设计和优化以适应 容 器 技 术 。Docker引 擎 的 基 础 组 件 是 Linuxcontainers(LXC)。各 种 工 具 的 丰 富 使 Docker应 用 迅 速 普 及 ,正如Solomon Hykes所说:Docker在正确的地点、正确的时间顺应了正确的趋势 — 即高效地构建应用[7]。隔离是Docker的重点,正如JVM隔离了硬件资源环境影响一样,Docker将容器外环境的改变变得不那么重要了,程序的移植变得象拷贝文件一样简单了。这给运维带来了极大的方便。利 用 SpringBoot Maven plugin 将 Maven 引入 SpringBoot 项目是一个关键,Spotify 的 docker-maven-plugin 插件可以用来构建 Maven 的Docker镜像。可以编写Dockerfile来指定特定的镜像层。之后可以将镜像推送到DockerHub上,DockerHub是一个类似GitHub原理的镜像托管平台。在项目开发阶段最好的做法是使用持续集成的做法,即使用Jenkins来结合Git Hooks,当代码 Push到 Git服务器后,Jenkins自动去执行shell脚本文件Pull的代码,又 Maven变异打包生成最新的镜像文件。最后再push到 DockerHub上 。装 有 Docker的服务器从DockerHub上的到镜像运行该镜像的所属容器从而完成整个部署过程。另外由于在SpringBoot中的模板引擎默认开启缓存,利 用 SpringLoaded实现类文件修改热部署,利 用 JRebel可以实现开发热部署,这样会极大提高开发调测效率。
SpringBoot在测试方面也带了很多的改变[8]。首先,在SpringBoot项目中按照其一惯的starter做法在项目中加入spring-boot-starter-test的依赖,其他的关于测试的依赖就不用再管理了。根 据 SpringBoot的最佳实践在项目src/test/java目录下添加测试类。其次,测试类SpringBoot使 用 @ springapplicationconfiguration 代替了 @contextConfiguration 配置 SpringBoot的应用上下文,还有两个常用的Annotation是 @RunWith(SpringJUnit4ClassRunner.class)和@WebApplication和@transactional保证测试操作的回滚,具体的测试方法就完全按照Junit的方式做了。在 controller层测试类为了 MockMvc而注入了 WebApplicationContext[9]。 这 里 充 分 利 用 了SpringMVC的测试功能。测试的过程可以总结归纳为以下过程,为项目准备测试的环境;通 过 MockMvc来模拟执行http请求;增加验证的JUnit Assert还有处理结果Assert。收到MvcResult后进行自定义Assert又从新进行下一步的异步请求;最后卸载掉测试用的MockMvc环境,完成测试。总之SpringBoot利用和SpringMVC的关系将测试变得简单实用,为后期自动化集成测试奠定良好的基础[10]。
4. SpringBoot监控和管理生产环境。
SpringBoot给 web系统开发带来的改变中一个重要的方面就是监控和管理生产环境[11]。如何实时监控应用系统信息的各项功能是否健康,就要通过系统各方面的性能安全指标数值来评估。这样可以在系统变得不稳定的时期就发现或解决问题,而不是系统功能停止时刻才发现,从而避免业务遭受打击。大规模互联网应用一定会有专门的网管系统,但应用系统内部情况就不会监控得那么细致了。Spring可以监控到什么信息呢,如:当前应用的所有配置、当前应用中所有的Bean的信息、所有配置属性、线程状态信息、当前环境信息、应用健康状况、当前应用的各项指标信息、所 有 @RequestMapping映射的路径、显示追踪信息以及所有EndPoint列表[12]。可以看到内容非常丰富而且实用。这些监控信息通过监控和管理端点的形式提供给开发者。而前提是在P0M文件中加入spring-boot-starter-actuator这个依赖。在创建项目时可以选择Actuator、web和 HATE0A S这几个模块。当项目部署完成可以通过http URL地址访问到这些监控信息,如 :http: //localhost: 8080/actuator 可以看到所有 EndPoint 列表;http: //localhost: 8080/beans可以看到所有Beans列表等。甚至还可以自定义端点对一些业务指标进行监控,这是任何市场盒装系统监控产品也做不到的[13]。另 外 SpringBoot在 web系统监控开发的提升开可以利用 JMX(Java Management Extensions , 即Java管理扩展)进行[14]。
三、结论
SpringBoot对于Spring平台无疑是巨大的提升[15]。无论在开发阶段还是部署测试阶段,甚至系统在线运行阶段,SpringBoot都在发挥着他的作用。使 web 系统开发在多方面整体提升。随着微服务的推广,作为底层支持的SpringBoot正在改变web应用开发模式[16]。
总之虽然Spring Boot给我们带来了类似于脚本语言开发的效率,但是Spring Boot里没有使用任何让我们意外的技术[17],完全是一个单纯的基于Spring的应用。如Spring Boot的自动配置是通过Spring4.x的@Conditional注解来实现的。并且Spring技术栈中的SpringCloud已经成为新一代微服务框架,成为比国内Dubbo的更加成熟的微服务宠儿。同时还有Spring Cloud Data Flow等成熟框架,这些都将影响着将来的开发模式和开发效率,并且这将会是一种趋势,就像Python适合来做机器学习一样。因为他们都是相关领域中最适合该生态环境的方式。
四、参考文献
[1] 张峰.应用SpringBoot改变web应用开发模式[J]. 科技创新与应用, 2017(23): 193-194.
[2] 汪云飞. JavaEE开发的颠覆者:Spring Boot实战[M]. 北京:电子工业出版社,2016:1-15.
[3] Pivotal 团队. Spring Boot Reference Guide1.5.3.RELEASE[OL]. 2017.
[4] 王永和, 张劲松, 邓安明, 周智勋. Spring Boot研究和应用[J]. 信息通信, 2016(10): 91-94.
[5] 杨家炜.基于Spring Boot的web设计与实现[J]. 轻工科技, 2016, 32(07): 86-89.
[6] 郑彬彬. 基于微服务的OJ系统重构与优化[D]. 上海:东华大学, 2017.
[7] Bhimani J, Yang Z, Mi N, et al. Docker Container Scheduler for I/O Intensive Applications running on NVMe SSDs[J]. 2018, 2(99): 1-1.
[8] Reddy K S P. Testing Spring Boot Applications[M]. Beginning Spring Boot 2. Apress, Berkeley, CA, 2017: 221-246.
[9] Reddy K S P. Getting Started with Spring Boot[M]. Beginning Spring Boot 2. Apress, Berkeley, CA, 2017: 21-33.
[10] Walls C. Spring Boot in action[M]. Manning Publications Co., 2016:21-34
[11] Felipe Gutierrez. Spring Boot, Simplifying Everything[M]. Apress: 2014-06-15:02-06
[12] Miller R A, Heitkamp E M. Spring boot: U.S. Patent Application 12/435,432[P]. 2010-11-11.
[13] Balalaie A, Heydarnoori A, Jamshidi P. Microservices architecture enables devops: Migration to a cloud-native architecture[J]. IEEE Software, 2016, 33(3): 42-52.
[14] Balalaie A, Heydarnoori A, Jamshidi P. Migrating to cloud-native architectures using microservices: an experience report[C].European Conference on Service-Oriented and Cloud Computing. Springer, Cham, 2015: 201-215.
[15] Webb P, Syer D, Long J, et al. Spring boot reference guide[J]. Part IV. Spring Boot features, 2013, 10(3): 24-25.
[16] Prieto Barreiro I, Varela F, Mandilara E. Monitoring of CERN's Data Interchange Protocol (DIP) System[J]. 2018, 3(33): 3-5.
[17] Varela F, Gonzalez Corral M, Podgorski S, et al. MARS: Easing Maintenance and Interventions for CERN Controls[J]. 2018, 3(11): 3-4.