Spring与设计模式总览

Spring框架中的设计模式详解

Spring框架不仅是Java企业级开发的主力军,其设计还蕴含了大量经典设计模式。这些模式贯穿于Spring的核心组件中,提升了框架的可维护性和扩展性。本文将深入探讨Spring框架中常见的设计模式及其应用。

1. 工厂模式(Factory Pattern)

工厂模式是最常见的设计模式之一。Spring使用工厂模式来创建和管理Bean的实例。

1.1 工厂方法模式

工厂方法模式通过定义一个创建对象的接口,让子类决定实例化哪个类。Spring中的FactoryBean就是一个很好的例子。

public interface FactoryBean<T> {
    T getObject() throws Exception;
    Class<?> getObjectType();
    boolean isSingleton();
}

通过实现FactoryBean接口,可以自定义Bean的创建逻辑。

1.2 抽象工厂模式

Spring的BeanFactoryApplicationContext实现了抽象工厂模式。ApplicationContext不仅继承了BeanFactory的所有功能,还提供了更强大的功能,如国际化、事件传播和声明式方式创建Bean等。

ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
MyBean myBean = context.getBean(MyBean.class);

2. 单例模式(Singleton Pattern)

单例模式确保一个类只有一个实例,并提供一个全局访问点。Spring默认使用单例模式管理Bean,这意味着一个Bean在整个Spring容器中只有一个实例。

<bean id="myBean" class="com.example.MyBean" scope="singleton"/>

通过配置scope属性,可以将Bean定义为单例。

3. 代理模式(Proxy Pattern)

代理模式用于为其他对象提供一种代理以控制对这个对象的访问。Spring AOP(面向切面编程)大量使用了代理模式。

3.1 JDK动态代理

Spring AOP使用JDK动态代理来为实现接口的类创建代理对象。

public interface MyService {
    void performTask();
}

public class MyServiceImpl implements MyService {
    @Override
    public void performTask() {
        System.out.println("Performing task...");
    }
}

3.2 CGLIB代理

对于没有实现接口的类,Spring使用CGLIB来创建代理对象。

public class MyService {
    public void performTask() {
        System.out.println("Performing task...");
    }
}

4. 模板方法模式(Template Method Pattern)

模板方法模式定义了一个算法的骨架,而将一些步骤延迟到子类中。Spring的JdbcTemplateRestTemplate等类广泛使用了模板方法模式。

public abstract class AbstractTemplate {
    public final void templateMethod() {
        step1();
        step2();
        step3();
    }

    protected abstract void step1();
    protected abstract void step2();
    protected abstract void step3();
}

通过继承AbstractTemplate类,可以实现具体的步骤逻辑。

5. 策略模式(Strategy Pattern)

策略模式允许定义一系列算法,并将每个算法封装起来,使它们可以互换。这种模式让算法的变化独立于使用算法的客户。Spring的TaskExecutorTransactionManagement等模块使用了策略模式。

public interface TaskExecutor {
    void execute(Runnable task);
}

public class SimpleTaskExecutor implements TaskExecutor {
    @Override
    public void execute(Runnable task) {
        new Thread(task).start();
    }
}

通过实现TaskExecutor接口,可以定义不同的任务执行策略。

6. 观察者模式(Observer Pattern)

观察者模式定义了对象间的一对多依赖关系,当一个对象改变状态时,所有依赖于它的对象都会收到通知并自动更新。Spring的事件驱动模型使用了观察者模式。

6.1 自定义事件

public class CustomEvent extends ApplicationEvent {
    public CustomEvent(Object source) {
        super(source);
    }
}

6.2 自定义事件监听器

@Component
public class CustomEventListener implements ApplicationListener<CustomEvent> {
    @Override
    public void onApplicationEvent(CustomEvent event) {
        System.out.println("Received custom event: " + event.getSource());
    }
}

6.3 发布事件

@Component
public class EventPublisher {
    @Autowired
    private ApplicationEventPublisher applicationEventPublisher;

    public void publishEvent() {
        CustomEvent event = new CustomEvent(this);
        applicationEventPublisher.publishEvent(event);
    }
}

7. 装饰模式(Decorator Pattern)

装饰模式在不改变对象接口的情况下,动态地扩展对象的功能。Spring中的BeanPostProcessorBeanFactoryPostProcessor使用了装饰模式。

BeanPostProcessor示例

@Component
public class CustomBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        // 在Bean初始化之前进行处理
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        // 在Bean初始化之后进行处理
        return bean;
    }
}

8. 适配器模式(Adapter Pattern)

适配器模式将一个类的接口转换成客户希望的另一个接口。Spring的HandlerAdapterController等使用了适配器模式。

public interface HandlerAdapter {
    boolean supports(Object handler);
    ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
}

通过实现HandlerAdapter接口,可以适配不同的控制器。

当然,Spring框架中还应用了其他许多设计模式。以下是一些额外的设计模式及其在Spring中的应用:

9. 桥接模式(Bridge Pattern)

桥接模式通过将抽象部分与实现部分分离,使它们可以独立变化。Spring的JdbcTemplate和各种数据库抽象模块使用了桥接模式。

  • 抽象部分:定义了抽象类,并包含一个对实现部分的引用。
  • 实现部分:定义实现类接口,具体实现类实现该接口。
public abstract class DatabaseConnection {
    protected DatabaseDriver driver;

    protected DatabaseConnection(DatabaseDriver driver) {
        this.driver = driver;
    }

    public abstract void connect();
}

public interface DatabaseDriver {
    void establishConnection();
}

通过桥接模式,数据库连接和具体的数据库驱动可以独立变化。

10. 外观模式(Facade Pattern)

外观模式通过提供一个统一的接口,用来访问子系统中的一群接口,从而让子系统更容易使用。Spring中的JdbcTemplateRestTemplate等类提供了简化数据库访问和HTTP请求的统一接口。

public class DatabaseFacade {
    private JdbcTemplate jdbcTemplate;

    public DatabaseFacade(DataSource dataSource) {
        this.jdbcTemplate = new JdbcTemplate(dataSource);
    }

    public void executeQuery(String sql) {
        jdbcTemplate.execute(sql);
    }
}

11. 组合模式(Composite Pattern)

组合模式允许你将对象组合成树形结构来表示"部分-整体"的层次结构。Spring的BeanFactoryApplicationContext使用了组合模式。

  • 组件:定义了组合对象和叶子对象的接口。
  • 叶子对象:实现组件接口,不包含子对象。
  • 组合对象:实现组件接口,包含子对象。
public interface Component {
    void operation();
}

public class Leaf implements Component {
    @Override
    public void operation() {
        System.out.println("Leaf operation");
    }
}

public class Composite implements Component {
    private List<Component> children = new ArrayList<>();

    @Override
    public void operation() {
        for (Component child : children) {
            child.operation();
        }
    }

    public void add(Component component) {
        children.add(component);
    }

    public void remove(Component component) {
        children.remove(component);
    }
}

12. 责任链模式(Chain of Responsibility Pattern)

责任链模式通过给多个对象处理请求的机会,避免请求的发送者与接收者之间的耦合。Spring的DispatcherServlet使用责任链模式来处理HTTP请求。

  • 处理器接口:定义处理请求的方法。
  • 具体处理器:实现处理器接口,并处理部分请求。
  • :将多个处理器链接起来。
public interface Handler {
    void setNext(Handler handler);
    void handleRequest(String request);
}

public abstract class AbstractHandler implements Handler {
    protected Handler nextHandler;

    @Override
    public void setNext(Handler handler) {
        this.nextHandler = handler;
    }

    @Override
    public void handleRequest(String request) {
        if (nextHandler != null) {
            nextHandler.handleRequest(request);
        }
    }
}

13. 享元模式(Flyweight Pattern)

享元模式通过共享对象来减少内存消耗。Spring的内置缓存机制和一些池化技术使用了享元模式。

  • 享元接口:定义共享对象的接口。
  • 具体享元:实现享元接口,提供共享的具体对象。
  • 享元工厂:负责创建和管理享元对象。
public interface Flyweight {
    void operation(String extrinsicState);
}

public class ConcreteFlyweight implements Flyweight {
    private String intrinsicState;

    public ConcreteFlyweight(String intrinsicState) {
        this.intrinsicState = intrinsicState;
    }

    @Override
    public void operation(String extrinsicState) {
        System.out.println("Intrinsic State = " + intrinsicState + ", Extrinsic State = " + extrinsicState);
    }
}

public class FlyweightFactory {
    private Map<String, Flyweight> flyweights = new HashMap<>();

    public Flyweight getFlyweight(String key) {
        if (!flyweights.containsKey(key)) {
            flyweights.put(key, new ConcreteFlyweight(key));
        }
        return flyweights.get(key);
    }
}

总结

Spring框架中设计模式的广泛应用展示了设计模式在构建灵活、可维护和可扩展系统中的重要性。通过理解和应用这些设计模式,我们开发人员可以更好地利用Spring框架,构建出高质量、可维护和可扩展的企业级应用程序。这些模式不仅提高了代码的可读性和可维护性,还增强了系统的扩展性和灵活性。在实际项目中,合理地应用设计模式和Spring特性,可以显著提升系统的设计质量和开发效率。后面会根据实际项目进行实战

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

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

相关文章

分布式 I/O 系统 BL200 Modbus TCP 耦合器

BL200 耦合器是一个数据采集和控制系统&#xff0c;基于强大的 32 位微处理器设计&#xff0c;采用 Linux 操作系统&#xff0c;支持 Modbus 协议&#xff0c;可以快速接入现场 PLC、SCADA 以及 ERP 系统&#xff0c; 内置逻辑控制、边缘计算应用&#xff0c;适用于 IIoT 和工业…

CyberVadis认证是什么

CyberVadis认证是一项全球性的、权威的、基于云的网络安全性评估和认证项目。它是由Altimeter公司开发的&#xff0c;专门针对云计算服务提供商、数据中心、软件即服务(SaaS)供应商、安全咨询服务公司和内部IT部门而设计的。 CyberVadis认证旨在评估和验证组织在网络安全方面的…

android中实现双列表联动功能

就是一个数据展示的功能&#xff0c;左边是目录、右边是详情列表。效果图如下&#xff1a; 实现的思路&#xff0c;就是左右一个列表&#xff0c;右边的列表里面嵌套一个列表&#xff0c;一共三个列表。 第一步&#xff1a;先写一个主页面布局文件 <?xml version"1…

在GPU上运行PyTorch

文章目录 1、查看GPU的CUDA版本2、下载CUDA版本3、安装cuDNN4、配置CUDA环境变量5、安装配置Anaconda6、使用Anaconda7、pycharm导入虚拟环境8、安装带GPU的PyTorch⭐9、总结 &#x1f343;作者介绍&#xff1a;双非本科大三网络工程专业在读&#xff0c;阿里云专家博主&#x…

轻量级自适用商城卡密发卡源码(可运营)

一款全开源非常好看的发卡源码。轻量级自适应个人自助发卡简介&#xff0c;这是一款二次开发的发卡平台源码修复原版bug,删除无用的代码。所有文件全部解密&#xff0c;只保留后台版权信息内容。大家放心使用&#xff0c;可以用于商业运营。轻量级自适应个人自助发卡。 源码下…

【海外云手机】静态住宅IP集成解决方案

航海大背景下&#xff0c;企业和个人用户对于网络隐私、稳定性以及跨国业务的需求日益增加。静态住宅IP与海外云手机的结合&#xff0c;提供了一种创新的集成解决方案&#xff0c;能够有效应对这些需求。 本篇文章分为三个部分&#xff1b;静态住宅优势、云手机优势、集成解决…

高翔【自动驾驶与机器人中的SLAM技术】学习笔记(一)——流形;

新建了一个专栏&#xff0c;仔细学习高翔的新书《自动驾驶与机器人中的SLAM技术》。 快速通读了一遍&#xff0c;发现还有很多需要深入学习的东西&#xff0c;因此二刷这本书。对于自己不懂的地方&#xff0c;通过这个笔记记录这个流程。 第一个问题&#xff1a;流形。 流形学…

Spring Boot项目的404是如何发生的

问题 在日常开发中&#xff0c;假如我们访问一个Sping容器中并不存在的路径&#xff0c;通常会返回404的报错&#xff0c;具体原因是什么呢&#xff1f; 结论 错误的访问会调用两次DispatcherServlet&#xff1a;第一次调用无法找到对应路径时&#xff0c;会给Response设置一个…

uniapp页面跳转传参和动态修改NavigationBarTitle

一、需求 比如聊天界面&#xff0c;需要在上方展示对方的名字&#xff0c;我们这样需要动态数值的&#xff0c;就不能写在pages配置项里面。 二、实现 我们并没有在pages里面配置固定的title名&#xff0c;我们需要动态传到talk&#xff0c;然后动态修改绑定到这个title。好在u…

从零开始学量化~Ptrade使用教程(六)——盘后定价交易、港股通与债券通用质押式回购

盘后固定价交易 实现科创板、创业板的盘后固定价交易&#xff0c;界面如下显示&#xff1a; 交易 输入科创板或创业板代码&#xff0c;选择委托方向&#xff0c;输入委托价格、委托数量&#xff0c;点击“买入”或“卖出”按钮进行委托。可出现一个委托提示框提示是否继续委托操…

HCNA VRP基础

交换机可以隔离冲突域&#xff0c;路由器可以隔离广播域&#xff0c;这两种设备在企业网络中应用越来越广泛。随着越来越多的终端接入到网络中&#xff0c;网络设备的负担也越来越重&#xff0c;这时网络设备可以通过专有的VRP系统来提升运行效率。通过路由平台VRP是华为公司数…

怎么录屏?Windows和Mac电脑都适用的3种方法

在数字化时代的浪潮中&#xff0c;电脑录屏已经成为一种必备技能。无论是为了制作教学视频&#xff0c;记录游戏的高光时刻、还是为了保存下欢乐时光&#xff0c;录屏功能都在我们当中发挥着重要的作用。但是怎么录屏也成为一个难题&#xff0c;有时候用的电脑不一样&#xff0…

基于搜索二叉树的停车收费管理系统

系统效果&#xff1a;录入汽车信息 查看汽车信息 收费信息查看 查询车库车辆 代码展示&#xff1a; //SearchBinaryTree.h #pragma once #include<iostream> #include<string> #include<time.h> #include<Windows.h> using namespace std;template<…

ArkTS学习笔记_UI界面的状态管理简述

ArkTS学习笔记_UI界面的状态管理简述 背景&#xff1a; 我们在UI开发中&#xff0c;绝大多数的UI界面都是动态的、有用户交互的&#xff0c;为了实现动态交互&#xff0c;引入了一个概念“状态”&#xff0c;它主要是用来记录管理UI界面的状态变化&#xff08;数据变化&#x…

08 模型演化根本 深度学习推荐算法的五大范式

易经》“九三&#xff1a;君于终日乾乾&#xff1b;夕惕若&#xff0c;厉无咎”。九三是指阳爻在卦中处于第三位&#xff0c;已经到达中位&#xff0c;惕龙指这个阶段逐渐理性&#xff0c;德才已经显现&#xff0c;会引人注目&#xff1b;但要反思自己的不足&#xff0c;努力不…

ubuntu上模拟串口通信

前言 有时候写了一些串口相关的程序&#xff0c;需要调试的时候&#xff0c;又没有硬件&#xff0c;或者需要等其他模块完成才能一起联调。这样搭建环境费时费力&#xff0c;很多问题等到最后联调才发现就已经很晚了。 本文提供一种在ubuntu环境下模拟串口&#xff0c;直接就可…

django报错(一):python manage.py makemigrations,显示“No changes detected”

执行python manage.py makemigrations命令无任何文件生成&#xff0c;结果显示“No changes detected”。 解决方案一&#xff1a; 1、执行命令&#xff1a;python manage.py makemigrations –empty appname 2、删除其中的0001_initial.py文件&#xff08;因为这个文件内容是…

vue2+antd实现表格合并;excel效果

效果图 一、html <template><div><a-table :columns"columns" :dataSource"dataSource" rowKey"id" :pagination"false" bordered><template slot"content1" slot-scope"text">{{text}}…

单臂路由组网实验,单臂路由的定义、适用情况、作用

一、定义 单臂路由是指通过在路由器的一个接口上配置许多子接口,从而实现原来相互隔离的不同VLAN之间的互通。 子接口:把路由器上的实际的物理接口划分为多个逻辑上的接口,这些被划分的逻辑接口就是子接口。 二、适用情况 用在没有三层交换机,却要实现不同VLAN之间的互…

element ui中el-form-item的属性rules的用法

目录 el-form-item的属性rules的用法 栗子 总结 实践应用 一、 定义静态的校验规则 二、定义动态的校验规则 el-form-item的属性rules的用法 在学习element ui 的Form表单组件时&#xff0c;学到el-form-item也有rules属性&#xff0c;但是对应这个属性如何使用&#x…