Java之武林盟主 - Spring

许多年之后,当讨论起Java开发的时候,可以不讨论安卓开发,可以不讨论多线程,可以不讨论流,可以不讨论JVM, 但Spring是一个绕不过去的话题.
Spring从诞生到现在已经有20年左右的历史,这个生命不如linux, 但也足够长了.
在前端界,还找不到和Spring框架相提并论的框架,Spring的框架在Java领域是没有对手的,可以说找不到竞品,前端至少是React和vuejs两家独大,而且也是最近几年才出来的产物.
这篇文章主要闲聊

  • 什么是Spring?
  • 为什么是Spring?
  • 如何实现一个Spring?
  • Spring实践?
  • Spring的发展
  • 拾遗

什么是Spring?

2002年10月, Rod Johnson出版了一版名为《Expoert One-on-One J2EE设计和开发》的书,书中指出了Java EE和EJB组件框架中的主要缺陷。在这本书里,他提出了基于普通Java类和注入依赖的更简单的方案.
在这本书发布不久之后,有两位开发者说服了Rod Johnson基于书上的代码创建一个开源基础框架的项目. 2003年三位开发者创建了一个项目, 开发者yann给框架取了一个很有诗意的名字”Spring”.有点类似中国文化里蕴含的一元复始,万象更新的意思.
所以Spring是一个框架,致力于简化Java开发

Spring有很多功能,如果不断的去砍掉一些功能,让Spring只具备最核心的功能,应该是

  • IOC
  • AOP
    这是Spring其他的功能的基础和起点

Spring当前最新的版本是5.0, 5.0要求的最低JDK版本是8, JavaEE规范是7. Spring的大版本更新至少要基于两个因素

  • 一个最低的JDK版本
  • 特定的JavaEE规范

为什么是Spring?

这个问题很简单,在当时从框架层面简化Java开发的只有Spring框架,并没有其他框架,可谓一家独大.
就好比创业的时候,选择了一个赛道,然后这个赛道上只有一家企业,等这家企业壮大了,只要不作死,其他企业想进来也没有机会了.

如何实现一个Spring?

整体设计目标

Spring框架所有做的事情都可以说是为了一个终极目的: 简化Java开发.

策略

  • 基于POJO的轻量级和最小侵入编程
    • POJO是简单的,那就说明是容易理解的,而且不含有杂质.
  • DI和面对接口实现松耦合编程
    • 隔离了接口和实现
  • 基于AOP和惯例的声明式编程
    • AOP是为了隔离了核心功能和非核心功能
    • 惯例是用户熟悉的事物
  • 基于AOP和模板减少样板式代码
    • 模版说明是一致的编程模型,减少重复代码.

战略背后的思想

基于上面的策略,可以总结出这些策略背后的思想

  • 符合用户的心智模型 - 简单,熟悉,一致
    • 用户喜欢简单和熟悉的东西. 因为简单的东西和熟悉的东西意味着可理解,可理解意味这可维护
    • 一致的编程模型。 对于类似的东西,不可能用方法A处理事物A, 方法B处理事物B, 而是要用一个统一的方法处理事物A和事物B
  • 隔离
    • 隔离抽象和和具体,抽象代表着稳定,具体代表着不稳定
    • 隔离核心和非核心,核心的东西代表着重要,非核心的东西代表着次要

上面这两大思想可以用来指导架构设计和类库设计.

模块图

  • Spring容器的三架马车, 三是个好数字,三生万物. Bean, Core, Context为Spring框架奠定了基石 * Bean
    Bean是Spring组件核心中核心,正如一部电视剧的主角一样,挪走了主角了,这部剧就没有什么看点了. 正如面向对象编程里,对象是第一核心,剩下的是对象的关系和行为。Spring Bean也是如此, Bean是Spring起点. Bean主要回答了三个问题
    • 如何定义一个Bean
    • 如何创建一个Bean
    • 如何解析一个Bean * Context
      Context赋予了Bean更丰富的内涵,让Bean活跃起来,变的更有生命力
    • 获得Bean列表
    • 解析资源
    • 发布事件
    • 国际化 * Core
      Core组件是一系列工具的集合, 它的某些概念与Bean没有直接关系,比如Log功能。Core这个名字其实取的不是特别好,会让人有点疑惑,会让人感觉Core组件就是核心, 核心意味着所有的组件都围绕着Core转,其实并不是,Spring的核心是Bean。拿打仗做个比喻, Bean是冲锋陷阵的士兵,Context是指挥官,协调管理这些士兵, 那么Core是什么呢?更多类似于后勤和伙夫, 从这里可以看出Core并不是核心. 所以把Core理解为Spring的瑞士军刀比较合适, 因为Core能提供某些贴心的小功能.

Spring实践?

展示

展示一般而言与Web有关,这里的展示意义更加宽泛一点,可以指手机,手表等任何显示设备. 展示层实现策略有两大方向

  • 前后端不分离
  • 前后端分离

数据

任何的信息都必须是可以存储的,或者叫做持久化。这样的信息是基本事实,可以给各种方式(比如机器学习)企业的决策提供依据。 数据存储有两大类型

  • 关系型数据
  • 非关系型数据

缓存

用户流量增加之后,为了获得更好的用户体验,减轻数据库的压力,需要一个能抗事的家伙. 这个就是缓存.

安全

对于大多数系统,必须回答两个问题

  • 这个用户是谁?
  • 这个用户能做什么?

消息

任何系统都不是孤立的,系统A想和系统B相互交流,有两种办法

  • 系统A调用系统B的接口
  • 引入一个系统M来隔离系统A和系统B, 这样系统A和系统B就完成隔离开了,符合正交的特性。换句话以后系统A即使消亡了,也与系统B没有什么关系. 这个M往往称做消息系统或者消息中间件.

其他

系统出了故障,我们希望能快速的去解决故障,而不是两眼一抹黑。换句话说,我们能对系统有掌控。 一般来说有如下方式

  • 日志
  • 监控

Spring的发展

Spring Boot

Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications that you can “just run”.

Spring Boot不是Spring的功能升级,而是简化了Spring的构建. 使用Spring Boot

  • 没有繁琐的XML的配置
  • 不需要操作Jar包之间的依赖关系
  • 内置了Jetty容器,不像之前要生成一个war包,然后拷贝到特定的jetty目录下.

两个例子

  • 我们知道汽车有一键启动的功能,在此之前我们要掏出钥匙,插入钥匙,启动。 做的事情都是启动,但很明显一键启动完全提高了效率.
  • 做过前端开发的朋友,应该知道create-react-app这个脚手架,可以大大的提搞开发者的效率,Spring-boot扮演的就是脚手架这个角色。 所以Spring boot从整个Spring的历史来看,它很重要,但没有革命性的东西。

Spring Cloud

Spring Cloud provides tools for developers to quickly build some of the common patterns in distributed systems

从这里可以看出, Spring Cloud的定位和明确

  • 聚焦于分布式的问题
  • 提供一致的编程模型. 比如在这里模型下面,服务发现框架可以从容易的从ZooKeeper切换到Consul

所以Spring Cloud的目标是非常宏大, 它不像Spring Shiro是为了解决某个特定的领域的问题, 它要是统一解决分布式领域的各种问题,具体一点就是微服务和云原生相关的问题, 可谓雄心勃勃。 来看看Spring Cloud都提供来哪些工具

  • Spring Cloud Eureka - 解决了服务注册和发现的问题
    • 竞品 - Nacos, k8s的Service(可以被Istio追踪,纳入servicemesh的管理)
  • Spring Cloud Ribbon - 解决了如何将流量公平得分配到每台机器的问题.
    • 竞品 - k8s的Service
  • Spring Cloud Hystrix - 解决流量过大时, 如何将让流量不再进来的问题.
    • 竞品 - Sentinel, k8s的Istio
  • Spring Cloud Zuul - 解决了流量是否合法,以及流量进来之后去哪里的问题.
    • 竞品 - Kong, k8s的Ingress
  • Spring Cloud Config - 解决了服务配置信息集中管理的问题
    • 竞品 - 携程的Apollo, k8s的ConfigMap和Secret
  • Spring Cloud Stream - 解决了不同服务之间相互通信的问题.
  • Spring Cloud Bus - 解决了不同服务之间如何共享信息的问题
  • Spring Cloud Sleuth - 解决了如何了解服务全貌这个问题
    • 竞品 - 推特的Zipkin, 大众点评的CAT
  • Spring Cloud Feign - 简化了服务的调用方式
  • Spring Boot Actuator - 解决了监控程序的问题
    • 竞品 - ZMon, DataDog

拾遗

官网中有一幅图,是从Spring boot到Spring Cloud, Spring Cloud DataFlow, 这幅图可以反应这三者之间的时间关系,但同时有个误区,它会给人传达这样一个意思

小学生 -> 中学生 -> 大学生

就是这三者是能力渐进增强的,其实并不是, Spring Boot充其量是个脚手架的角色,和Spring Cloud不是同一个层次的事物,放在一起不好比较.

如果把Spring, Spring Boot, Spring Cloud放在一起,那它们应该是一个什么样的关系呢?

高尔夫1.4T -> 高尔夫2.0T -> 途观

Spring Boot让Spring变得更快,Spring Cloud让Spring 能力更强