Spring中使用到的设计模式及其源码分析

前言

众所周知,Spring框架是一个强大而灵活的开发框架。这不,上次的面试刚问到这些,没防住!!!因此下来总结一下。这篇文章主要介绍Spring中使用到的设计模式,自己做个面试复盘,同时希望能帮助到其他小伙伴儿们。

在这里插入图片描述

工厂模式

相信大家面试题都背过,Spring通过工厂模式来创建和管理Bean的实例。工厂模式主要定义了一个用于创建对象的接口,让子类决定实例化哪一个类。在Spring中,BeanFactoryApplicationContext接口是实现工厂模式的关键。

那么什么是BeanFactoryApplicationContext呢???👇👇👇

BeanFactory是Spring中最底层的容器接口,它提供了基础的依赖注入功能。ApplicationContext扩展了BeanFactory,并添加了更多高级功能,比如国际化、事件传播、资源加载等(这个也是面试重点!!!)。

我们以ApplicationContext为例,它提供了getBean(String name)方法来获取Bean实例。当调用这个方法的时候,ApplicationContext会根据配置信息创建或获取Bean实例。

	ApplicationContext context = new ClassPathXmlApplicationContext("springDemo.xml");  

	MyBean myBean = context.getBean("myBean", MyBean.class);

AbstractApplicationContextgetBean方法通过调用getBeanFactory().getBean()来实际获取Bean实例。而BeanFactory的实现类(比如DefaultListableBeanFactory)负责根据Bean的定义和依赖关系来创建和管理Bean实例。

单例模式

Spring中的Bean默认都是单例的,因此在整个Spring IoC容器中,每个Bean只会有一个实例。这是通过Bean的scope属性来进行控制的,当scopesingleton时,就表示使用单例模式。

翻阅了Spring的源码发现:👇👇👇

Spring通过DefaultSingletonBeanRegistry类中的singletonObjects(类型为ConcurrentHashMap)来管理单例Bean的实例。当请求一个Bean时,Spring会首先检查这个Map中是否已存在该Bean的实例,如果存在则直接返回,否则创建新的实例并添加到Map中。

	private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);  
	public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {  
	    Assert.notNull(beanName, "Bean name must not be null");  
	    synchronized (this.singletonObjects) {  
	        Object singletonObject = this.singletonObjects.get(beanName);  
	        if (singletonObject == null) {  
	            // 创建新的Bean实例
	            singletonObject = singletonFactory.getObject();  
	            // 添加到单例注册表中
	            this.singletonObjects.put(beanName, singletonObject);  
	        }  
	        return singletonObject;  
	    }  
	}

代理模式

这道题相信大家都会,面试经常被问到哈哈。Spring的AOP功能中使用了代理模式。AOP通过在目标方法执行前后添加额外的行为(比如日志、事务管理这些),而这些额外的行为是通过代理对象来实现的。Spring提供了两种代理方式:JDK动态代理和CGLIB代理。

Spring的AOP实现主要在DefaultAopProxyFactory类中。这个类负责根据配置决定使用哪种代理方式,并创建代理对象。

	if (isProxyTargetClass()) {  
	    // 使用CGLIB代理  
	    return createCglibProxy(beanClassLoader, beanFactory, beanClass, beanName, targetSource, interceptedMethods, proxyTargetClass);  
	} else {  
	    // 使用JDK动态代理  
	    return createJdkDynamicProxy(beanClassLoader, beanFactory, beanClass, interfaces, interceptedMethods, proxyTargetClass);  
	}

createJdkDynamicProxy这个方法中,Spring通过Proxy.newProxyInstance方法创建一个实现了目标对象接口的代理对象,并将所有调用转发到目标对象,同时还可以在调用前后插入额外的行为。

模板方法模式

谈论到模板方法模式,相信大家都较为熟悉。比如在前面提过的AQS中也有模板方法模式的影子。

在Spring的JdbcTemplateHibernateTemplate这些类中,都使用了模板方法模式。这些类定义了一个操作中的算法骨架,而将一些步骤延迟到子类中实现。

JdbcTemplate为例,它定义了如queryupdate等方法,这些方法包含了数据库操作的通用流程(打开连接、执行SQL、处理结果集、关闭连接等),而具体的SQL语句和参数则由调用者提供。

观察者模式

Spring的事件驱动模型使用了观察者模式。当某个事件发生时,所有注册为该事件监听器的对象都会收到通知,并且根据需要作出响应。

Spring的ApplicationEvent和ApplicationListener接口是实现观察者模式的关键。ApplicationEvent是事件对象,包含了事件的信息;ApplicationListener是监听器接口,定义了处理事件的方法。

public class CustomEvent extends ApplicationEvent {  
    private final String message;  
    public CustomEvent(Object source, String message) {  
        super(source);  
        this.message = message;  
    }  
  
    public String getMessage() {  
        return message;  
    }  
}  
  
// 实现监听器  
@Component  
public class CustomEventListener implements ApplicationListener<CustomEvent> {  
    @Override  
    public void onApplicationEvent(CustomEvent event) {  
        // 处理事件  
        System.out.println("Received custom event - " + event.getMessage());  
    }  
}

在Spring的AbstractApplicationContext中,通过ApplicationEventMulticaster来管理事件的发布和监听。当事件被发布时,ApplicationEventMulticaster会通知所有注册的监听器。

策略模式

策略模式在Spring中主要用于定义一系列的算法,并将每一个算法封装起来,使它们可以互相替换。相信大家看过Spring中bean的生命周期这道面试题。Spring的BeanFactoryPostProcessorBeanPostProcessor这些接口可以被视为策略模式的应用,因为它们允许开发者在Bean的创建和初始化过程中插入自定义的逻辑。

BeanFactoryPostProcessor允许在BeanFactory标准初始化之后,修改BeanFactory的内容。这个时候我们可以实现这个接口来定义自己的策略,然后在Spring的配置文件中注册这个Bean。

Spring还有一些其他的设计模式,看到这里面试以及能防得住了,后续再介绍其他的设计模式。

本篇文章到这里就结束了,感谢各位小伙伴们的支持!

在这里插入图片描述

  • 38
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 11
    评论
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小威要向诸佬学习呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值