Spring框架中的11种设计模式(设计模式之美)

适配器模式

例如Controller的三种实现方式:

  • @Controller注解
  • 实现Controller接口 + xml配置文件:配置DemoController与URL的对应关系
  • 实现Servlet接口 + xml配置文件:配置DemoController类与URL的对应关系

不同的Controller如何调用呢?可以通过适配器模式。

terface HandlerAdapter {
  boolean supports(Object var1);

  ModelAndView handle(HttpServletRequest var1, HttpServletResponse var2, Object var3) throws Exception;

  long getLastModified(HttpServletRequest var1, Object var2);
}

// 对应实现Controller接口的Controller
public class SimpleControllerHandlerAdapter implements HandlerAdapter {
  public SimpleControllerHandlerAdapter() {
  }

  public boolean supports(Object handler) {
    return handler instanceof Controller;
  }

  public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    return ((Controller)handler).handleRequest(request, response);
  }

  public long getLastModified(HttpServletRequest request, Object handler) {
    return handler instanceof LastModified ? ((LastModified)handler).getLastModified(request) : -1L;
  }
}

// 对应实现Servlet接口的Controller
public class SimpleServletHandlerAdapter implements HandlerAdapter 

//AnnotationMethodHandlerAdapter对应通过注解实现的Controller,

策略模式

Spring AOP是通过动态代理来实现的。Spring支持两种动态代理实现方式,一种是JDK提供的动态代理实现方式,另一种是Cglib提供的动态代理实现方式。Spring会在运行时动态地选择不同的动态代理实现方式:策略模式包含三部分,策略的定义、创建和使用。

public interface AopProxy {
  Object getProxy();
  Object getProxy(ClassLoader var1);
}

public interface AopProxyFactory {
  AopProxy createAopProxy(AdvisedSupport var1) throws AopConfigException;
}

public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
  public DefaultAopProxyFactory() {
  }

  public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
    if (!config.isOptimize() && !config.isProxyTargetClass() && !this.hasNoUserSuppliedProxyInterfaces(config)) {
      return new JdkDynamicAopProxy(config);
    } else {
      Class<?> targetClass = config.getTargetClass();
      if (targetClass == null) {
        throw new AopConfigException("TargetSource cannot determine target class: Either an interface or a target is required for proxy creation.");
      } else {
        return (AopProxy)(!targetClass.isInterface() && !Proxy.isProxyClass(targetClass) ? new ObjenesisCglibAopProxy(config) : new JdkDynamicAopProxy(config));
      }
    }
  }

  //用来判断用哪个动态代理实现方式
  private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) {
    Class<?>[] ifcs = config.getProxiedInterfaces();
    return ifcs.length == 0 || ifcs.length == 1 && SpringProxy.class.isAssignableFrom(ifcs[0]);
  }
}

组合模式

Spring Cache提供了一套抽象的Cache接口。使用它我们能够统一不同缓存实现(Redis、Google Guava…)的不同的访问方式。Spring中针对不同缓存实现的不同缓存访问类,都依赖这个接口,比如:EhCacheCache、GuavaCache、NoOpCache、RedisCache、JCacheCache、ConcurrentMapCache、CaffeineCache。Cache接口的源码如下所示:

public interface Cache {
  String getName();
  Object getNativeCache();
  Cache.ValueWrapper get(Object var1);
  <T> T get(Object var1, Class<T> var2);
  <T> T get(Object var1, Callable<T> var2);
  void put(Object var1, Object var2);
  Cache.ValueWrapper putIfAbsent(Object var1, Object var2);
  void evict(Object var1);
  void clear();

  public static class ValueRetrievalException extends RuntimeException {
    private final Object key;

    public ValueRetrievalException(Object key, Callable<?> loader, Throwable ex) {
      super(String.format("Value for key '%s' could not be loaded using '%s'", key, loader), ex);
      this.key = key;
    }

    public Object getKey() {
      return this.key;
    }
  }

  public interface ValueWrapper {
    Object get();
  }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

虚拟机数据恢复—KVM虚拟机磁盘文件数据恢复案例

虚拟化数据恢复环境&故障&#xff1a; KVM是Kernel-based Virtual Machine的简称&#xff0c;是一个开源的系统虚拟化模块&#xff0c;自Linux2.6.20版本之后集成在Linux的各个主要发行版本中。KVM使用Linux自身的调度器进行管理。 本案例中的服务器操作系统为Linux&#x…

官宣|Apache Paimon 毕业成为顶级项目,数据湖步入实时新篇章!

北京时间 2024 年 4 月 16日&#xff0c;开源软件基金会 Apache Software Foundation&#xff08;以下简称 ASF&#xff09;正式宣布 Apache Paimon 毕业成为 Apache 顶级项目(TLP, Top Level Project)。经过社区的共同努力和持续创新&#xff0c;Apache Paimon 在构建实时数据…

【剪映专业版】10时间线工具:主轨磁吸、自动吸附、联动、预览轴、全局缩放预览

视频课程&#xff1a;B站有知公开课【剪映电脑版教程】 主轨&#xff1a;有封面标志的轨道才是主轨。 主轨磁吸&#xff1a;开启后&#xff0c;在主轨上移动素材&#xff0c;自动向前磁吸&#xff0c;在其他轨道上移动无此效果&#xff1b;关闭后&#xff0c;不自动向前磁吸&…

艾迪比皮具携手工博科技SAP ERP公有云,打造数字化转型新标杆

4月1日&#xff0c;广州市艾迪比皮具有限公司&#xff08;以下简称“艾迪比”&#xff09;SAP S/4HANA Cloud Public Edition&#xff08;以下简称“SAP ERP公有云”&#xff09;项目正式启动。双方项目组领导、成员出席本次项目启动会&#xff0c;为未来项目的顺利实施打下坚实…

Python程序设计 元组和集合

教学案例七 元组和集合 1. 根据年月日计算周几 根据输入的年号、月号、日号&#xff0c;计算是周几(中文、英文) 蔡勒公式 通过蔡勒&#xff08;Zeller&#xff09;公式可计算星期几 w:星期; w对7取模得:0-星期日,1-星期一,2-星期二,3-星期三,4-星期四,5-星期五,6-星期六 c&…

【hive】lateral view侧视图

文档地址&#xff1a;https://cwiki.apache.org/confluence/display/Hive/LanguageManualLateralView 1.介绍2.语法3.code demo1&#xff09;单重侧视图2&#xff09;多重侧视图3&#xff09;tips&#xff1a;lateral view outer 1.介绍 lateral view也叫侧视图&#xff0c;属…

【electron3】electron将数据写入本地数据库

安装 yarn add sqlite3 --save连接并调用数据库&#xff0c;创建表 createDB.ts文件内容 const sqlite3 require(sqlite3) const NODE_ENV process.env.NODE_ENV const path require(path) const { app } require(electron) let DB_PATH path.join(app.getAppPath(), /…

LDF、DBC、BIN、HEX、S19、BLF、asc、csv、ARXML、slx等(未完待续)

文章目录 如题如题 LDF是LIN报文格式文件,把这个直接拖到软件里面,可以发报文和接收报文 DBC是CAN报文格式文件,把这个直接拖到软件里面,可以发报文和接收报文 BIN文件烧录在BOOT里面(stm32),有人喜欢叫固件,这个固件就是bin文件,bin文件比hex文件体积小 其实BOOT也…

Android apk包使用360加固工具的加固步骤

1&#xff0c;准备好已经签名打包的apk包。 2&#xff0c;在360加固官方网站下载加固exe软件。三六零天御-企业移动应用安全一站式服务平台 3&#xff0c;步骤一&#xff0c;添加加固包&#xff0c;进行加固&#xff0c;并输出加固包&#xff1a; 4&#xff0c;步骤二&#…

预算不足千元SSL证书该怎么选?

随着互联网安全概念日渐深入人心&#xff0c;越来越多的企业或个人为自己的网站加装SSL证书&#xff1b;那对于个人或者小小微企业&#xff0c;预算不足千元的情况下该怎么选择SSL证书呢&#xff1f;可以从以下几个方面进行考量&#xff0c;以确保在有限的预算内获得满足基本安…

Linux编辑器-vim的使用

vim的基本概念 vim的三种模式(其实有好多模式&#xff0c;目前掌握这3种即可),分别是命令模式&#xff08;command mode&#xff09;、插 入模式&#xff08;Insert mode&#xff09;和底行模式&#xff08;last line mode&#xff09;&#xff0c;各模式的功能区分如下&#…

苹果开发初学者指南:Xcode 如何为运行的 App 添加环境变量(Environmental Variable)

概览 Xcode 15 在运行 SwiftUI 代码时突然报告如下警告&#xff1a; Error: this application, or a library it uses, has passed an invalid numeric value (NaN, or not-a-number) to CoreGraphics API and this value is being ignored. Please fix this problem. 不仅如此…

李沐45_SSD实现——自学笔记

主体思路&#xff1a; 1.生成一堆锚框 2.根据真实标签为每个锚框打标(类别、偏移、mask) 3.模型为每个锚框做一个预测(类别、偏移) 4.计算上述二者的差异损失&#xff0c;以更新模型weights 先读取一张图像。 它的高度和宽度分别为561和728像素。 %matplotlib inline import …

NVM下载、NVM配置、NVM常用命令

NVM(nodejs版本管理切换工具)下载、配置、常用命令 0、NVM常用命令 nvm off // 禁用node.js版本管理(不卸载任何东西) nvm on // 启用node.js版本管理 nvm install <version> // 安装node.js的命名 version是版本号 例…

良友:献上今天(打开心窗说亮话)- 沟通篇

目录 一 二 三 四 五 六 七 八 九 十 十一 十二 十三

【Python小游戏】植物大战僵尸的实现与源码分享

文章目录 Python版植物大战僵尸环境要求方法源码分享初始化页面&#xff08;部分&#xff09;地图搭建&#xff08;部分&#xff09;定义植物类 &#xff08;部分&#xff09;定义僵尸类&#xff08;部分&#xff09;游戏运行入口 游戏源码获取 Python版植物大战僵尸 已有的植…

vscode调试文件(C++,ROS和cmake文件)

VsCode调试文件 参考文档&#xff1a; code.visualstudio.com/docs/editor/variables-reference code.visualstudio.com/docs/editor/tasks 主要修改task.json下的"args"、launch.json中的"program",“args” 注意task.json中的label以及launch.json中…

OpenCV 学习笔记2 C++

1.图像直方图 直方图&#xff08;Histogram&#xff09;是图像处理中常用的工具&#xff0c;它表示图像中每个像素强度值的分布情况。在OpenCV中&#xff0c;可以使用 cv::calcHist 函数来计算图像的直方图。 图像直方图是一种展示图像像素强度分布的统计图表。它显示了图像中…

市场份额第一!博睿数据持续领跑中国APM市场

近日&#xff0c;全球领先的IT市场研究和咨询公司IDC发布《中国IT统一运维软件产品市场跟踪报告&#xff0c;2023H2》。报告显示&#xff0c;2023下半年博睿数据以 17.6%的市场份额蝉联 APM(应用性能监控)市场第一。2023年全年博睿数据以18.8%的市场份额持续领跑中国APM市场。 …

实现联系人前后端界面,实现分页查询04.15

实现联系人前后端界面&#xff0c;实现分页查询项目包-CSDN博客 项目结构 数据库中建立两个表&#xff1a; 完整的后端目录 建立联系人People表&#xff0c;分组Type表&#xff0c;实现对应实体类 根据需求在mapper中写对应的sql语句 查询所有&#xff0c;删除&#xff0c;添…
最新文章