赞
踩
本文将系统梳理Spring Boot实战内容,并把这些内容划分为核心容器、Web服务、数据访问、内置缓存、并发编程、监控和扩展六大主题。
针对核心容器,将深入讨论Spring所具备的依赖注入和面向切面编程这两项基础功能。
对于依赖注入而言,Spring容器为开发人员提供了字段注入、构造器注入和Setter方法注入这三种实现方式。不同的依赖注入方式各有其优缺点,下面将对它们进行详细分析,并给出Spring依赖注入的实现原理。
当讨论如何管理对象之间的依赖关系时,循环依赖是一个不同回避的话题。Spring的依赖注入机制在解决循环依赖问题时采用了三级缓存机制。这是Spring在设计和实现上的一大特色。从实战角度讲,把握Bean的作用域、灵活使用注解配置、设置组件扫描范围以及对不同配置进行性能分析是日常使用Spring依赖注入时所需要掌握的一些开发技巧。
对于AOP而言,Spring框架提供了连接点、通知、切点等核心概念,以及@Before、@After、@Around、@AfterThrowing和@AfterReturning等注解。通过这些主机,开发人员可以很轻松地在业务代码中嵌入切面。
AOP的使用虽然简单,但它背后的实现原理并不简单。想要理解AOP的原理就需要对动态代理机制有深入的了解。Java世界中典型的JDK动态代理和CGLIB动态代理,在Spring中也都得到广泛应用。从实战角度讲,灵活使用切点表达式、确保类内部调用能够应用代理、避免代理机制引起多次初始化过程以及优先使用JDK动态代理是常见的开发技巧。
在当下的互联网应用程序中,前后端分离的开发模式大行其道,Web服务是开发人员使用Spring Boot实现HTTP端点的基本手段。
对于轻量级Web服务开发而言,传统的SpringMVC仍然是目前主流的技术体系,可以使用Controller来暴露HTTP端点,并通过RestTemplate工具类实现对远程服务的访问。
这种基于HTTP的请求-响应模式采用的是RESTful架构风格。但是请注意,真正的RESTful风格存在一个成熟度模型,代表最高成熟度登记的并不是我们日常使用的WebMVC,而是HATEOAS(基于超媒体的应用状态引擎)。Spring也专门为实现HATEOAS提供了Spring HATEOAS框架。
针对前后端分离的开发场景,如何设计合理且高效的交互Web API是前端和后台开发人员日常开发工作的一大难点和痛点。传统的RESTful风格能够很好运作的前提是提取资源的需求和API的设计之间能够得到匹配。如果这一条件无法满足,那么就会出现前端无法预判响应的数据格式、无法根据请求控制对应的返回结果以及需要发送多次请求等诸多问题。GraphQL为这些问题提供了解决方案,而Spring家族的Spring GraphQL框架也正式成为Spring顶级项目
随着Spring5的正式发布,响应式编程迎来全新发展时期。响应式编程能够提高系统的弹性。Spring在Project Reactor这款响应式编程框架的基础上开发了Spring WebFlux框架。相较Spring WebMVC,Spring WebFlux实现了异步、非阻塞的远程交互过程。
在响应式的世界中,关于Web服务还有一个重要的话题,即网络协议。我们知道HTTP是一款典型的请求-响应式的应用层协议。而请求-响应模式在很多应用场景中存在局限性,也无法与响应式编程体系进行整合。在这个背景下就诞生了RSocket协议,该协议提供了四种不同的Web交互模式 ,并且可以与响应式编程技术完美融合。Spring目前已经全面拥抱RSocket协议,并专门提供了Spring RSocket框架。
对于互联网应用而言,缓存可以说是一种基础技术组件。缓存的应用非常广泛,开发人员可以使用位于应用程序内部的本地缓存,也可以使用对于独立服务器上的分布式缓存。从3.1版本开始,Spring开始为开发人员提供了一个非常好用的缓存组件。
1、系统缓存
Spring的缓存机制非常灵活,提供了一组包括@Cacheable/@CachePut和@CacheEvict在内的注解来简化系统缓存的使用过程,可以通过这些逐渐对容器中的任意Bean或者Bean的方法添加缓存功能。开发人员在使用系统缓存时,需要做的事情就是指定缓存键,并对缓存功能进行配置。
作为一款通用的技术组件,缓存的实现方式也有很多种,包括支持分布式场景的Redis和Hazelcast,以及支持应用程序本地缓存的EhCache、Guava、Caffeine等。Spring作为一款主流的开源框架,通过对缓存操作进行高度抽象,为开发人员提供一套统一的API。这种针对缓存的抽象机制值得我们深入学习。
从实战角度讲,Spring缓存提供的统一编程API有时候并不能满足我们的需求。所以,自定义缓存注解、自定义缓存键生成器,以及自定义Cache和CacheManager是日常开发过程中经常用到的开发技巧。
2、认证缓存
Spring的认证缓存可以认为是系统缓存在安全管理领域的一种具体的应用场景。想要使用应用缓存,首先需要你对Spring家族中另一款具有代表性的安全框架Spring Secutiry有一定的了解。Spring Security中内置了一套完整的认证和授权机制,开发人员可以通过引入认证缓存提供安全性处理的性能。
同样,认证缓存作为系统缓存的具体应用,与Spring Security框架中的用户认证过程紧密结合并完成全流程的缓存操作,也能为开发人员更好的应用Spring缓存机制提供参考。
3、内置缓存的实战案例
针对Spring内置的缓存组件,讲分别针对系统缓存和认证缓存实现两个案例,即Spring缓存案例和Spring Security认证缓存案例。
在高并发场景下,缓存机制可以很好的解决系统性能瓶颈问题。Spring缓存内部集成了一批具有代表性的第三方缓存工具。在安全性处理场景中,如果用户认证数据的获取和处理过程需要与数据库进行交互,那么这种交互过程很可能对系统性能带来负面影响。这时候,解决这个问题的一种有效方案是将用户身份验证缓存他恶性的时间长度。
无论互联网应用还是传统软件,对于任何一个系统而言,数据的存储和访问都是必不可少的。数据访问层的构建可能会涉及多种不同形式的数据存储媒介。Spring Boot对关系型数据库访问的支持包括两大部分内容,即基于JDBC规范的Spring JDBC组件和支持ORM的Spring Data组件。
1、Spring JDBC
针对关系型数据库,Java世界中应用最广泛的就是JDBC规范,但JDBC规范是一种偏底层的实现技术,不适合直接面向业务开发。Spring框架基于JDBC规范,提供了一整套的解决方案,包括常用的JdbcTemplate模版工具类,以及在JdbcTemplate基础上构建的能够进一步简化数据访问操作的SimpleJdbcInsert等组件。
在Spring中,以-Template结尾的模版工具类应用非常广泛,而这些模版工具类的设计和实现最大限度地发挥了模版方法设计模式的优势,并基于回调机制解决了原生JDBC等组件面临的复杂性问题。JdbcTemplate作为一种典型的模版工具类,其实现过程非常具有代表性,为开发人员如何对底层框架进行封装和扩展提供了范本。
从实战角度讲,Spring JDBC的使用涉及很多技术细节,例如优化事务隔离等级、优化Fetch Size、优化连接池配置、选择合适的Statement、使用批处理等。
2、Spring Data
事实上,JdbcTemplate是相对偏底层的一个工具类。作为系统开发中最重要的基础功能之一,数据访问层组件的开发方式在Spring Boot中也得到进一步的简化,并充分发挥了Spring家族中另一个重要成员Spring Data的作用。Spring Data是基于Repository架构模式抽象出来的一套统一的数据访问组件,是一款支持JPA等多种数据访问规范的ORM框架。
在使用Hibernate等ORM框架时,会碰到经典的N+1性能问题。针对该问题存在多种解决方案,常见的包括JOIN FETCH和Entity Graph机制。对于JOIN FETCH,可以使用JPA查询语句和Criteria这两种实现方式;而对于Entity Graph,可以使用Named Entity Graph 和Dynamic Entity Graph。
对于任何请求-响应模式下的处理过程,都需要关注请求的响应能力。对于Web请求而言,我们希望服务端能够快速返回处理结果,从而提高系统的响应能力。而Spring框架也针对这一诉求给出了它的解决方案,就是并发编程模型。Spring对于并发编程模型的支持包括两个方面。一方面,Spring提供了@Async注解来实现通用的异步编程能力,并提供WebAsyncTask组件来实现面向Web的异步处理机制。另一方面,Spring还提供了两个更高级的并发编程工具类,即任务执行器TaskExecutor以及任务调度器TaskScheduler。
1、Spring Async
异步处理的主要优势是调用方不必等待被调用方完成执行过程,因为可以在一个单独的线程中执行一个方法。JDK为开发人员提供了Future、CompletableFuture等支持异步编程的实现工具。而Spring异步编程模型在此基础上提供了一个全新的@Async注解,该注解可以与JDK中的Future机制以及线程池进行无缝整合。
Spring的@Async注解是通用的,可以用它来完成针对任意场景的异步处理流程。随着Spring Boot的诞生,特定于Web请求处理过程,也出现了WebAsyncTask这一专门的异步任务组件。相较@Async注解,WebAsyncTask为开发人员提供了更灵活的异步任务处理机制。
2、Spring任务执行器和调度器
JDK中自带的执行器(Executor)组件使用起来非常方便,本质上是在所有内部县城管理任务上提供了一个抽象层。而Spring提供TaskExecutor接口作为Executor的扩展,包含了一大批非常有用的实现类。
有时候,我们需要以固定的时间间隔执行任务,这就需要引入任务调度的概念。Spring专门针对任务调度场景提供了TaskScheduler组件。基于Spring,我们将看到如何使用@Scheduled注解来对任务进行调度。
从实战角度讲,Spring框架分别针对不同的应用场景提供了SimpleAsyncTaskExecutor、SyncTaskExecutor、ConcurrentTaskExecutor等TaskExecutor。根据具体需求,灵活使用多种TaskExecutor是一项开发技巧。
作为新一代开发框架,相较传统Spring,Spring Boot提供了更为全面的技术支持。第一,Spring Boot 为开发提供了一个非常有特色的主题,就是系统监控。其次,Spring Boot实际上形成了一个生态系统。
(1)系统监控
系统监控是Spring Boot中引入的一项全新功能,对于管理应用程序运行时状态非常有用。Spring Boot Actuator组件是承载系统监控功能的组件,通过一系列HTTP端点提供系统监控功能。
对于系统监控而言 ,可视化管理界面是必不可少的。Sping Boot基于Actuator组件提供的监控端点专门实现了Admin Server组件,用于监控基于Spring Boot开发的应用程序。
从实战角度讲,监控的目的是发现系统中存在的性能问题并找到对应的解决方案。在Spring Boot中,通过替换默认组件提升系统性能是一项最佳实践。
(2)生态扩展
关于系统扩展性,开发人员可以基于Spring Boot提供的Starter机制来将业务系统与Spring Boot进行集成。事实上,业界知名的开源框架都可以使用对应的Spring Boot Starter组件,从而方便我们基于Spring Boot来使用这些框架。
作为Spring Clouid框架的基础,Spring Boot也在微服务系统的构建过程中扮演重要角色,Spring Cloud技术体系下的单个微服务实际上就是一个Spring Boot应用程序。
云原生是当下技术发展的热点,Spring也提供了专门针对云原生架构的Spring Ntive框架。Spring Native基于GraalVM虚拟机技术,为开发人员提供了更快的启动时间以及更好的内存占用。
针对Spring Boot的系统监控和生态扩展主题,后面将给出一系列案例分析,包括扩展Actuator端点案例分析、自定义Actuator端点分析、Admin Server系统监控案例分析等。
Spring Boot Actuator组件默认提供了一系列监控端点,最常用的就是info端点和health端点,将通过案例介绍如何对这些端点进行扩展。
对系统性能进行可视化监控一直是一个难题,但Spring Boot Admin Server的出现为我们提供了简单好用的解决方案。可以通过Admin Server监控系统运行时的各项关键指标。
在基于Starter集成Spring Boot的案例分析中,我们的分析方式不是自己从零实现一个Spring Boot Starter组件,而是参考业界主流的开源框架,通过源码解析来深入理解Spring Boot Starter的实现方式。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。