02-Spring Core中的设计模式分析

Spring Core中的设计模式分析

1. 单例模式 (Singleton Pattern)

源码分析:

在Spring框架中,Bean默认是单例的。这意味着在整个Spring IoC容器中,只有一个Bean实例。Spring通过DefaultSingletonBeanRegistry来实现单例模式。

public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);@Overridepublic Object getSingleton(String beanName) {return this.singletonObjects.get(beanName);}@Overridepublic void registerSingleton(String beanName, Object singletonObject) {synchronized (this.singletonObjects) {this.singletonObjects.put(beanName, singletonObject);}}
}

设计思想:

单例模式确保一个类只有一个实例,并提供一个全局访问点。在Spring中,单例模式用于确保每个Bean在容器中只有一个实例,从而节省内存和资源。

解决的问题:

  • 资源共享:确保同一个Bean实例在应用程序的不同部分被共享,避免重复创建Bean实例。
  • 性能优化:通过避免多次实例化,节省了内存和资源,提高了性能。

优缺点:

  • 优点
    • 节省内存:减少了Bean实例的数量。
    • 资源共享:确保应用程序中的Bean实例可以共享状态。
  • 缺点
    • 全局状态:单例Bean可能会导致全局状态的管理变得复杂。
    • 线程安全:单例Bean需要处理线程安全问题。
2. 工厂方法模式 (Factory Method Pattern)

源码分析:

Spring使用BeanFactoryApplicationContext来创建和管理Bean实例。BeanFactory接口定义了获取Bean的方法,而具体的创建逻辑由子类实现。

public interface BeanFactory {Object getBean(String name) throws BeansException;<T> T getBean(String name, Class<T> requiredType) throws BeansException;
}public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory {@Overridepublic Object getBean(String name) throws BeansException {return doGetBean(name, null, null, false);}protected <T> T doGetBean(final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly) {// 创建或获取Bean的逻辑}
}

设计思想:

工厂方法模式通过定义一个创建对象的接口,将对象的实际创建工作推迟到子类中实现。这使得代码可以更加灵活和可扩展。

解决的问题:

  • 对象创建的灵活性:通过工厂方法,可以根据具体的需求创建不同类型的对象,而无需修改现有代码。
  • 解耦:工厂方法将对象的创建过程与使用过程解耦,降低了代码的耦合性。

优缺点:

  • 优点
    • 灵活性:可以根据需求创建不同类型的对象。
    • 解耦:对象的创建过程与使用过程分离,降低了代码的耦合度。
  • 缺点
    • 复杂性:增加了代码的复杂性,因为需要额外的工厂类和方法。
3. 模板方法模式 (Template Method Pattern)

源码分析:

Spring使用模板方法模式在AbstractApplicationContext类中定义了一些通用的操作流程,如refresh()方法。

public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext {@Overridepublic void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {prepareRefresh();ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();prepareBeanFactory(beanFactory);postProcessBeanFactory(beanFactory);invokeBeanFactoryPostProcessors(beanFactory);registerBeanPostProcessors(beanFactory);initMessageSource();initApplicationEventMulticaster();onRefresh();registerListeners();finishBeanFactoryInitialization(beanFactory);finishRefresh();}}protected void prepareRefresh() {// 准备刷新上下文的逻辑}protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {// 获取新的BeanFactory的逻辑}// 其他方法
}

设计思想:

模板方法模式通过在基类中定义一个算法的骨架,并将具体的步骤延迟到子类实现,从而使得算法的结构可以在不改变算法结构的情况下得到复用和扩展。

解决的问题:

  • 代码复用:通过在基类中定义通用的操作流程,子类可以复用这些通用逻辑。
  • 代码扩展:子类可以在不修改基类的情况下,定制具体的操作步骤,实现代码的扩展。

优缺点:

  • 优点
    • 复用性:基类中的通用逻辑可以被多个子类复用。
    • 可扩展性:子类可以在不修改基类的情况下扩展功能。
  • 缺点
    • 灵活性:模板方法模式在设计时需要考虑到未来的扩展需求,可能会增加设计的复杂性。
    • 子类依赖:子类必须实现基类中定义的抽象方法,增加了子类的实现负担。

总结

Spring Core模块通过使用单例模式、工厂方法模式和模板方法模式,提高了代码的灵活性、可维护性和可扩展性。单例模式确保Bean实例的唯一性和资源共享,工厂方法模式解耦了对象的创建和使用,模板方法模式则提供了复用和扩展通用操作流程的能力。每种模式都有其独特的优势和劣势,但它们在Spring中的应用无疑增强了框架的整体设计和实现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/873999.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android Launcher3桌面图标样式修改(添加圆角)

1.源码类&#xff1a;LauncherActivityCachingLogic.java /** Copyright (C) 2018 The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You…

js修改hash的方法

关键&#xff1a; window.onhashchange (event) > {// do something }hash变化包括 js修改hash手动修改url的hash浏览器前进、后退 js修改hash: location.href "#user";在vue-router等路由组件中如何实现history模式呢&#xff1f; 关键函数&#xff1a;hi…

【学习笔记】Redis学习笔记——第14章 客户端

第14章 服务器 14.1 命令请求的执行过程 14.1.1 发送命令请求 客户端将发送的命令准换成协议格式然后发送给服务器 14.1.2 读取命令请求 1>保存命令至客户端状态输入缓冲区 2>提取命令参数及参数个数保存至客户端状态的argv与argc字段中 3>获取命令执行器并执行命…

Flink CDC 同步表至Paimon 写数据流程,write算子和commit算子。

Flink CDC 同步表至Paimon 写数据流程,write算子和commit算子。(未吃透版) 流程图 一般基本flink cdc 任务同步数据至paimon表时包含3个算子,source、write、global commit。 source端一般是flink connector实现的连接源端进行获取数据的过程,本文探究的是 source算子获…

Haproxy服务

目录 一.haproxy介绍 1.主要特点和功能 2.haproxy 调度算法 3.haproxy 与nginx 和lvs的区别 二.安装 haproxy 服务 1. yum安装 2.第三方rpm 安装 3.编译安装haproxy 三.配置文件详解 1.官方地址配置文件官方帮助文档 2.HAProxy 的配置文件haproxy.cfg由两大部分组成&…

Synchronized升级到重量级锁会发生什么?

我们从网上看到很多&#xff0c;升级到重量锁的时候不会降级&#xff0c;再来线程都是重量级锁 今天我们来实验一把真的是这样的吗 1.首选导入Java对象内存布局的工具库&#xff1a; <dependency><groupId>org.openjdk.jol</groupId><artifactId>jol-…

【moyu】河北省职工职业技能大赛决赛

[32m [33mMOYU [32m[0m 工作不算争取价值&#xff0c;是劳动换取酬劳&#xff1b; 工作的时候偷闲才是为自己争取价值。 [32m[0m****************************************************** ******************* 让我摸个鱼吧&#xff01; ******************* *****************…

二叉树---最大二叉树

题目&#xff1a; 给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建: 创建一个根节点&#xff0c;其值为 nums 中的最大值。递归地在最大值 左边 的 子数组前缀上 构建左子树。递归地在最大值 右边 的 子数组后缀上 构建右子树。 返回 nums…

web前端 React 框架面试200题(四)

面试题 97. React 两种路由模式的区别&#xff1f;hash和history&#xff1f; 参考回答&#xff1a; 1: hash路由 hash模式是通过改变锚点(#)来更新页面URL&#xff0c;并不会触发页面重新加载&#xff0c;我们可以通过window.onhashchange监听到hash的改变&#xff0c;从而处…

什么是内网穿透?

前言 我们常常会听到“内网穿透”这个术语&#xff0c;但对于很多人来说&#xff0c;它可能还比较陌生。作为一个在网络世界中摸索了一段时间的使用者&#xff0c;我来和大家分享一下我对内网穿透的理解。 目录 一、内网穿透介绍 二、发现 三、特点 四、优势 简单来说&am…

初识godot游戏引擎并安装

简介 Godot是一款自由开源、由社区驱动的2D和3D游戏引擎。游戏开发虽复杂&#xff0c;却蕴含一定的通用规律&#xff0c;正是为了简化这些通用化的工作&#xff0c;游戏引擎应运而生。Godot引擎作为一款功能丰富的跨平台游戏引擎&#xff0c;通过统一的界面支持创建2D和3D游戏。…

web前端 React 框架面试200题(五)

面试题 129. React.forwardRef是什么&#xff1f;它有什么作用&#xff1f; 参考回答&#xff1a; React.forwardRef 会创建一个React组件&#xff0c;这个组件能够将其接受的 ref 属性转发到其组件树下的另一个组件中。这种技术并不常见&#xff0c;但在以下两种场景中特别有…

Git使用技巧

rebase & merge 先说结论&#xff0c;rebase比较适用于私人分支&#xff0c;可以把主干分支上其他人开发的功能拉到自己的分支上&#xff0c;并且是一条线&#xff1b;merge则主要适用于主分支&#xff0c;可以将其他人的代码合并上去&#xff0c;因为要保留主分支的完整历…

opencv读写路径包含中文的文件

读文件 opencv直接读写路径包含中文的文件会出错。这是因为 cv2.imread 内部处理文件路径时&#xff0c;默认使用的是 C 标准库中的字符串处理函数&#xff0c;这些函数对于非 ASCII 字符可能处理不当&#xff0c;导致无法正确读取文件。 1、使用 numpy.fromfi…

JavaWeb笔记_Cookie

一.会话技术概述 在日常生活中,A和B之间在打电话过程中一连串的你问我答就是一个会话 在BS模型中,会话可以理解为通过浏览器访问服务端的资源,点击超链接可以进行资源的跳转,直到浏览器关闭过程叫做会话 我们使用会话技术可以解决的是整个会话过程中(通过浏览器浏览服务…

css-01-如何实现“文本过长(文本在一行排),超出部分被省略号代替”

目录 需求代码代码解释 需求 最近写一个项目&#xff0c;遇到了一个问题&#xff0c;就是希望实现下面这种文字效果&#xff1a;文字在一行排&#xff0c;超出的部分用省略号代替 代码 <!DOCTYPE html> <html lang"en"><head><meta charset…

【芯片设计- RTL 数字逻辑设计入门 番外篇 12 -- SoC 设计中的 ECO】

请阅读【ARM AMBA AXI 总线 文章专栏导读】 请阅读【芯片设计 RTL 数字逻辑设计扫盲 】 转自&#xff1a;简单了解SoC设计中的ECO — 快乐的芯片工程师 文章目录 ECO 概述Pre-Mask ECO&#xff08;预掩模ECO&#xff09;芯片设计前端与后端的区别 Post-Mask ECO&#xff08;后…

IAR环境下STM32+IAP方案的实现

--基于STM32F103ZET6的UART通讯实现 一、什么是IAP&#xff0c;为什么要IAP IAP即为In Application Programming(在应用中编程)&#xff0c;一般情况下&#xff0c;以STM32F10x系列芯片为主控制器的设备在出厂时就已经使用J-Link仿真器将应用代码烧录了&#xff0c;如果在设备使…

BM34 判断是不是二叉搜索树

1.题目描述 给定一个二叉树根节点&#xff0c;请你判断这棵树是不是二叉搜索树。 二叉搜索树满足每个节点的左子树上的所有节点均小于当前节点且右子树上的所有节点均大于当前节点。 例&#xff1a; 图1 图2 数据范围&#xff1a;节点数量满足 1≤&#x1d45b;≤104 1≤n≤104…

SpringMVC的底层工作原理?

1.用户发送请求至前端控制器DispatcherServlet. 2.DispatcherServlet 收到请求调用 HandlerMapping 处理器映射器 3.HandlerMapping找到具体的处理器(可以根据 xml 配置、注解进行查找&#xff09;&#xff0c;生成处理器及处理器拦截器(如果有则生成)一并返回给DispatcherSe…