【Spring】Spring 中的设计模式

按照模式的应用目标分类,设计模式可以分为创建型模式、结构型模式和行为型模式。

  • 创建型模式:是对对象创建过程的各种问题和解决方案的总结,包括各种工厂模式(Factory、Abstract Factory)、单例模式(Singleton)、构建器模式(Builder)、原型模式(ProtoType)
  • 结构型模式:是针对软件设计结构的总结,关注于类、对象继承、组合方式的实践经验。常见的结构型模式,包括桥接模式(Bridge)、适配器模式(Adapter)、装饰者模式(Decorator)、代理模式(Proxy)、组合模式(Composite)、外观模式(Facade)、享元模式(Flyweight)等
  • 行为型模式:是从类或对象之间交互、职责划分等角度总结的模式。比较常见的行为型模式有策略模式(Strategy)、解释器模式(Interpreter)、命令模式(Command)、观察者模式(Observer)、迭代器模式(Iterator)、模板方法模式(Template Method)、访问者模式(Visitor)

单例模式 Singleton

Ensure a class only has one instance, and provide a global point of access to it

注意区分 Singleton Pattern 与 Spring 中的 Singleton Bean

根据单例模式的目的 ,显然 Spring 中的 singleton bean 并非实现了单例模式,singleton bean 只能保证每个容器内,相同 id 的 bean 单实例只有一份。id 不相同的 bean 可以重复存在

当然 Spring 中也用到了单例模式,例如

  • org.springframework.transaction.TransactionDefinition#withDefaults
  • org.springframework.aop.TruePointcut#INSTANCE
  • org.springframework.aop.interceptor.ExposeInvocationInterceptor#ADVISOR
  • org.springframework.core.annotation.AnnotationAwareOrderComparator#INSTANCE
  • org.springframework.core.OrderComparator#INSTANCE

建造者模式 Builder

Separate the construction of a complex object from its representation so that the same construction process can create different representations

它的主要亮点有三处:

  1. 较为灵活的构建产品对象
  2. 在不执行最后 build 方法前,产品对象都不可用
  3. 构建过程采用链式调用,看起来比较爽

Spring 中体现 Builder 模式的地方:

  • org.springframework.beans.factory.support.BeanDefinitionBuilder
  • org.springframework.web.util.UriComponentsBuilder
  • org.springframework.http.ResponseEntity.HeadersBuilder
  • org.springframework.http.ResponseEntity.BodyBuilder

工厂方法模式 Factory Method

Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses

工厂模式的目的:让接口和实现相分离,降低耦合。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。

根据上面的定义,Spring 中的 ApplicationContextBeanFactory 中的 getBean() 都可以视为工厂方法,它隐藏了 bean (产品)的创建过程和具体实现。


https://www.cnblogs.com/yssjun/p/11102162.html

  • 简单工厂:在方法内通过判断传入的类型是什么创建出对应的对象,里面会有大量的 if/else 逻辑,不利于扩展
  • 工厂方法:提供一个 AbstractFactory,实现多个工厂子类,各自实现自己的逻辑,生产出对应的产品对象
  • 抽象工厂:同样提供一个 AbstractFactory,实现多个工厂子类,其中每个子类里提供多个方法,用于支持生产不同类型的产品对象

Spring 中其它工厂:

  • org.springframework.beans.factory.FactoryBean
  • @Bean 标注的静态方法及实例方法
  • ObjectFactory 及 ObjectProvider

前两种工厂主要封装第三方的 bean 的创建过程,后两种工厂可以推迟 bean 创建,解决循环依赖及单例注入多例等问题

适配器模式 Adapter

Convert the interface of a class into another interface clients expect. Adapter lets classes work together that couldn’t otherwise because of incompatible interfaces

典型的实现有两处:

  • org.springframework.web.servlet.HandlerAdapter – 因为控制器实现有各种各样,比如有
    • 大家熟悉的 @RequestMapping 标注的控制器实现
    • 传统的基于 Controller 接口(不是 @Controller注解啊)的实现
    • 较新的基于 RouterFunction 接口的实现
    • 它们的处理方法都不一样,为了统一调用,必须适配为 HandlerAdapter 接口
  • org.springframework.beans.factory.support.DisposableBeanAdapter – 因为销毁方法多种多样,因此都要适配为 DisposableBean 来统一调用销毁方法

有的 HandlerAdapter 适配器是用来适配调用 @ReqeuestMapping,有的是适配调用基于 Controller 接口的。DispatcherServlet 通过适配器来调用 Controller 里的具体方法。

组合模式 Composite

Compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly

组合模式的典型实现为各种解析器:参数解析器方法返回值解析器异常解析器视图解析器

  • org.springframework.web.method.support.HandlerMethodArgumentResolverComposite(多种不同的参数解析器组合起来,组合器内的集合就是各种参数解析器,使用组合器的统一调用接口来实现多个分散的解析器的有序调用
  • org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite
  • org.springframework.web.servlet.handler.HandlerExceptionResolverComposite
  • org.springframework.web.servlet.view.ViewResolverComposite

composite 对象的作用是将分散的调用集中起来,统一调用入口。它的特征是,与具体干活的类实现同一个接口,当调用 composite 对象的接口方法时,其实是委托具体干活的实现来完成。

装饰器模式 Decorator

Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality

装饰器模式:对一个对象动态的增加一些职责和功能。解决子类扩展方式提供功能增强的问题:子类扩展需要把所有父类的方法都继承。使用装饰器模式就可以增加一些额外的功能。

典型实现:

  • org.springframework.web.util.ContentCachingRequestWrapper
  • Spring Session 中的 SessionRepositoryRequestWrapper,将 将普通的 HttpRequest 进行了包装,这样 Controller 层在调用HttpRequest.getSession() 时,真正在执行的就是包装后的 SessionRepositoryRequestWrappergetSession() 方法了

代理模式 Proxy

Provide a surrogate or placeholder for another object to control access to it

装饰器模式注重的是功能增强,避免子类继承方式进行功能扩展,而代理模式更注重控制目标的访问。侧重控制和访问,增强其实是由切面方法实现的,代理主要是为了控制访问。

典型实现:

  • org.springframework.aop.framework.JdkDynamicAopProxy:jdk 代理
  • org.springframework.aop.framework.ObjenesisCglibAopProxy:cglib 代理

AOP 中就是用了代理模式,使用 ProyFactory 为对象创建动态代理对象。

责任链模式 Chain of Responsibility

Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it

典型实现:

  • org.springframework.web.servlet.HandlerInterceptor

各种拦截器都是责任链模式,每一个拦截器只负责调用下一个拦截器的方法,最后一个拦截器再执行目标方法。

观察者模式 Observer

Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically

典型实现:

  • org.springframework.context.ApplicationListener:接收事件
  • org.springframework.context.event.ApplicationEventMulticaster:发送事件
  • org.springframework.context.ApplicationEvent:事件

策略模式 Strategy

Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it

典型实现:

  • org.springframework.beans.factory.support.InstantiationStrategy
  • org.springframework.core.annotation.MergedAnnotations.SearchStrategy:查找注解时,使用多个策略,判断是去当前类中查找呢还是父类查找呢
  • org.springframework.boot.autoconfigure.condition.SearchStrategy:条件判断,当前bean是在哪个容器里呢

根据开发人员的选择,执行相应的策略。

模板方法模式 Template Method

Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm’s structure

典型实现:

  • 大部分以 Template 命名的类,如 JdbcTemplateTransactionTemplate
  • 很多以 Abstract 命名的类,如 AbstractApplicationContext

父类没有实现方法内容,只是提供一个基础架构。子类继承后自己实现。JUC 里也有很多模板方法模式的实现。