当前位置: 首页 > news >正文

Spring中的设计模式

Spring 框架中用到的设计模式包括:

  • 工厂设计模式: Spring 使用工厂模式通过BeanFactoryApplicationContext创建 bean 对象。
  • 代理设计模式: Spring AOP 功能的实现。
  • 单例设计模式: Spring 中的 Bean 默认都是单例的。
  • 模板方法模式: Spring 中jdbcTemplatehibernateTemplate等以 Template 结尾的对数据库操作的类,它们就使用到了模板模式。
  • 包装器设计模式: 我们的项目需要连接多个数据库,而且不同的客户在每次访问中根据需要会去访问不同的数据库。这种模式让我们可以根据客户的需求能够动态切换不同的数据源。
  • 观察者模式:Spring 事件驱动模型就是观察者模式很经典的一个应用。
  • 适配器模式:Spring AOP 的增强或通知(Advice)使用到了适配器模式、spring MVC 中也是用到了适配器模式适配Controller
  • ……

控制反转(IoC)和依赖注入(DI)

IoC(Inversion of Control,控制反转)是 Spring 中一个非常非常重要的概念,它不是什么技术,而是一种解耦的设计思想。

IoC 是一个原则,而不是一个模式,以下模式(但不限于)实现了 IoC 原则。

控制反转怎么理解呢?

举个例子:"对象 a 依赖了对象 b,当对象 a 需要使用对象 b 的时候必须自己去创建。但是当系统引入了 IOC 容器后, 对象 a 和对象 b 之间就失去了直接的联系。这个时候,当对象 a 需要使用 对象 b 的时候, 我们可以指定 IOC 容器去创建一个对象 b 注入到对象 a 中"。 对象 a 获得依赖对象 b 的过程,由主动行为变为了被动行为,控制权反转,这就是控制反转名字的由来。

DI(Dependency Inject,依赖注入)是实现控制反转的一种设计模式,依赖注入就是将实例变量传入到一个对象中去。

工厂设计模式

Spring 使用工厂模式可以通过BeanFactoryApplicationContext创建 bean 对象。

两者对比:

  • BeanFactory:延迟注入(使用到某个 bean 的时候才会注入),相比于ApplicationContext来说会占用更少的内存,程序启动速度更快。
  • ApplicationContext:容器启动的时候,不管你用没用到,一次性创建所有 bean 。BeanFactory仅提供了最基本的依赖注入支持,ApplicationContext扩展了BeanFactory,除了有BeanFactory的功能还有额外更多功能,所以一般开发人员使用ApplicationContext会更多。

单例设计模式

使用单例模式的好处:

  • 对于频繁使用的对象,可以省略创建对象所花费的时间,这对于那些重量级对象而言,是非常可观的一笔系统开销;
  • 由于 new 操作的次数减少,因而对系统内存的使用频率也会降低,这将减轻 GC 压力,缩短 GC 停顿时间。

Spring 中 bean 的默认作用域就是 singleton(单例)的。

// 通过 ConcurrentHashMap(线程安全) 实现单例注册表 private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(64); public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) { Assert.notNull(beanName, "'beanName' must not be null"); synchronized (this.singletonObjects) { // 检查缓存中是否存在实例 Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { //...省略了很多代码 try { singletonObject = singletonFactory.getObject(); } //...省略了很多代码 // 如果实例对象在不存在,我们注册到单例注册表中。 addSingleton(beanName, singletonObject); } return (singletonObject != NULL_OBJECT ? singletonObject : null); } } //将对象添加到单例注册表 protected void addSingleton(String beanName, Object singletonObject) { synchronized (this.singletonObjects) { this.singletonObjects.put(beanName, (singletonObject != null ? singletonObject : NULL_OBJECT)); } } }

代理设计模式

代理模式在 AOP 中的应用

详见:Spring - 基础知识 - AOP

模板方法

模板方法模式是一种行为设计模式,它定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。 模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤的实现方式。

Spring 中JdbcTemplateHibernateTemplate等以 Template 结尾的对数据库操作的类,它们就使用到了模板模式。一般情况下,我们都是使用继承的方式来实现模板模式,但是 Spring 并没有使用这种方式,而是使用 Callback 模式与模板方法模式配合,既达到了代码复用的效果,同时增加了灵活性。

观察者模式

观察者模式介绍详见 - 设计模式

Spring 事件驱动模型就是观察者模式很经典的一个应用。Spring 事件驱动模型非常有用,在很多场景都可以解耦我们的代码。比如我们每次添加商品的时候都需要重新更新商品索引,这个时候就可以利用观察者模式来解决这个问题。

Spring 的事件流程

  • 定义一个事件: 实现一个继承自ApplicationEvent,并且写相应的构造函数;
  • 定义一个事件监听者:实现ApplicationListener接口,重写onApplicationEvent()方法;
  • 使用事件发布者发布消息: 可以通过ApplicationEventPublisherpublishEvent()方法发布消息。

适配器模式

适配器模式介绍详见 - 设计模式

Spring AOP中的适配器模式

Spring AOP 的增强或通知(Advice)使用到了适配器模式,与之相关的接口是AdvisorAdapter

Advice 常用的类型有:BeforeAdvice(目标方法调用前,前置通知)、AfterAdvice(目标方法调用后,后置通知)、AfterReturningAdvice(目标方法执行结束后,return 之前)等等。每个类型 Advice(通知)都有对应的拦截器:MethodBeforeAdviceInterceptorAfterReturningAdviceInterceptorThrowsAdviceInterceptor等等。

Spring 预定义的通知要通过对应的适配器,适配成MethodInterceptor接口(方法拦截器)类型的对象(如:MethodBeforeAdviceAdapter通过调用getInterceptor方法,将MethodBeforeAdvice适配成MethodBeforeAdviceInterceptor)。

Spring MVC中的适配器模式

在 Spring MVC 中,DispatcherServlet根据请求信息调用HandlerMapping,解析请求对应的Handler。解析到对应的Handler(也就是我们平常说的Controller控制器)后,开始由HandlerAdapter适配器处理。HandlerAdapter作为期望接口,具体的适配器实现类用于对目标类进行适配,Controller作为需要适配的类。

装饰者模式

装饰者模式可以动态地给对象添加一些额外的属性或行为。

相比于使用继承,装饰者模式更加灵活。简单点儿说就是当我们需要修改原有的功能,但我们又不愿直接去修改原有的代码时,设计一个 Decorator 套在原有代码外面。其实在 JDK 中就有很多地方用到了装饰者模式,比如InputStream家族,InputStream类下有FileInputStream(读取文件)、BufferedInputStream(增加缓存,使读取文件速度大大提升)等子类都在不修改InputStream代码的情况下扩展了它的功能。

Spring 中配置 DataSource 的时候,DataSource 可能是不同的数据库和数据源。我们能否根据客户的需求在少修改原有类的代码下动态切换不同的数据源?这个时候就要用到装饰者模式(这一点我自己还没太理解具体原理)。Spring 中用到的包装器模式在类名上含有Wrapper或者Decorator。这些类基本上都是动态地给一个对象添加一些额外的职责。

http://www.jsqmd.com/news/115138/

相关文章:

  • 无线调试革命来了,Open-AutoGLM如何彻底改变你的开发流程?
  • 【Open-AutoGLM性能飞跃秘诀】:无线调试开启后效率提升300%的真相
  • 当开题报告遇上 paperzz:把 “头秃时刻” 变成 “一杯咖啡的事儿”
  • Open-AutoGLM Docker部署实战(专家级配置全公开)
  • Open-AutoGLM WiFi配置(从入门到精通,仅需这一篇)
  • 为什么你的Open-AutoGLM下载总失败?:90%人都忽略的网络优化细节
  • 2025索尼相机适配存储卡推荐榜-专业影像创作的存储选择 - 真知灼见33
  • 论文开题总卡壳?paperzz:让 AI 帮你把 “难开头” 变成 “好开头”
  • 非root环境下如何部署Open-AutoGLM?5个必知的安全避坑方案
  • 揭秘Open-AutoGLM与vLLM集成难点:5步实现高性能推理部署
  • WiFi连接失败怎么办?,Open-AutoGLM专家级排错全流程解析
  • Open-AutoGLM如何秒连WiFi?:工程师不会告诉你的4种高效方案
  • 从单机到分布式:大数据计算模式的演进之路
  • 高质量软件测试的核心要素
  • 【Open-AutoGLM性能飞跃指南】:6步完成安卓14底层优化,流畅度提升200%
  • spring16,17-加载properties文件,容器
  • Python小游戏制作:如何实现可配置的跨分辨率界面布局
  • 【硬核底层】万字长文搞定高并发:从 CPU 缓存一致性到 Java 内存模型 (JMM) 的终极解密
  • 揭秘Open-AutoGLM与安卓13兼容性问题:3个你必须立即更新的配置文件
  • Open-AutoGLM重试机制调优全攻略,打造企业级高可用AI管道
  • (Open-AutoGLM + 安卓13)高危适配警告:不处理这2个行为变更将导致崩溃率飙升
  • 面试官问Redis主从延迟导致脏数据读怎么解决?
  • Java中的JVM(虚拟机)是什么,新书小白带你入门,收藏这篇就够了
  • Java中的JVM(虚拟机)是什么,新书小白带你入门,收藏这篇就够了
  • Java中的JVM(虚拟机)是什么,新书小白带你入门,收藏这篇就够了
  • 【首发评测】Gemini 3 Flash 霸榜:1/4 的价格竟反超 2.5 Pro?“Thinking”架构开启 AI 效率新纪元
  • 为什么99%的开发者首次安装Open-AutoGLM都会踩坑?,真相在这里
  • 2025年度十大苗木批发基地供应商口碑推荐,丝棉木/国槐/栾树/白蜡/紫薇/无刺枸骨球/樱花/红叶石楠/苗木苗木批发基地种植选哪家 - 品牌推荐师
  • 构建高效的软件测试体系:从策略到实践的全面框架
  • 2025 年12月国产远控软件综合横测报告