什么是Spring设计模式:单例、工厂与代理

设计模式

单例模式(singleton)

Spring默认将Bean创建为单例,避免重复创建对象带来的性能开销

  • 目的:确保一个类只有一个实例,并且提供一个全局访问点

  • 应用场景:数据库连接池、日志记录器、配置管理器

    java 复制代码
    @Component
    public class MyService{
    	//默认是单例
    }
    //如果要修改作用域,可以用`@Scope("prototype")`

    一般在面试中可能会问手撕单例模式,一般面试最希望的成品是:

    java 复制代码
    public class Singleton{
    	private static volatile Singleton instance;
    	private Singleton(){}
    	
    	public static Singleton getInstance(){
    		if(instance == null){
    			synchronized(Singleton.class){
    				if(instance == null){
    				instance = new Singleton();
    				}
    			}
    		}
    		return instance;
    	}
    }
    1. 一定要加volatile保证可见性+禁止指令重排序,因为instance = new Singleton();并非一个原子操作,会经历3步,其他线程可能还没等对象初始化完,就操作了

    2. DCL需要Double-check:

      1. 第一次检查(无锁):提高性能。如果实例已经创建,直接返回,避免每次都加锁。
      2. 第二次检查(有锁):保证线程安全。防止多个线程同时通过第一次检查后,都进入 synchronized 块并各自 new 一个实例。

      总结:"DCL 中的两次 null 检查各有作用:

      • 第一次检查在同步块外,是为了避免每次调用都加锁,提升性能;
      • 第二次检查在 synchronized 块内,是为了防止多个线程同时通过第一次检查后,重复创建实例。

      同时,instance 字段必须用 volatile 修饰,禁止指令重排序,确保其他线程不会拿到一个尚未完全初始化的对象。"

    Spring单例!=JVM单例:Spring单例是容器级单例(每个ApplicationContext一个实例),不是JVM全局单例、如果有两个ApplicationContext那么就有两个MyService

工厂方法模式(Factory Method)

Spring 的 BeanFactoryApplicationContext 是典型的 工厂模式应用(更准确地说,是简单工厂的变体)。

不直接new对象,而是通过工厂来获取

  • 目的:定义一个创建对象的接口,但让子类决定序列化哪一个类

  • 应用场景:日志记录器、不同数据库驱动的创建

    java 复制代码
    ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
    MyService service = context.getBean(MyService.class); 
    // 工厂方法

    Spring IOC容器本质就是一个工厂,负责创建管理Bean不需要手动new,通过getBean()或依赖注入来获取,实现创建域使用的解耦

代理模式(Proxy Pattern)

实现AOP

通过代理对象,在不修改原类的情况下增强功能

java 复制代码
@Service
public class UserService {
    @Transactional // Spring 会为这个方法生成代理,加入事务控制
    public void saveUser() { ... }
}

Spring会根据情况选择:

  • JDK动态代理(基于接口)
  • CGLIB代理(基于子类)

补充说明:

如果目标类实现了接口 → 默认使用 JDK 动态代理

如果目标类没有实现接口 → 使用 CGLIB 代理 (可通过配置强制使用 CGLIB)

(观察者模式)------事件驱动

虽然有时被误称为'生产-消费',但 Spring 的事件机制本质上是 观察者模式,而非基于队列的生产-消费者模型。

在Spring中更准确地体现为事件监听机制,为了实现组件间的松耦合通信

java 复制代码
// 定义事件
public class UserRegisteredEvent extends ApplicationEvent { ... }

// 发布事件
applicationContext.publishEvent(new UserRegisteredEvent(user));

// 监听事件
@Component
public class EmailListener {
    @EventListener
    public void handleUserRegistered(UserRegisteredEvent event) {
        // 发邮件
    }
}

Spring 提供了基于观察者模式的事件机制。通过 publishEvent() 发布事件,多个监听器可以异步或同步响应,实现模块解耦。比如用户注册后触发邮件发送、积分增加等操作。

相关推荐
XiYang-DING1 小时前
【Java EE】阻塞队列(BlockingQueue)
java·java-ee
AndreasEmil2 小时前
基于多设计模式的抽奖系统 - 测试报告
java·selenium·设计模式·postman
长安11082 小时前
设计模式----工厂模式
设计模式
悟05152 小时前
设计模式-状态模式
设计模式·状态模式
Seven972 小时前
Tomcat Server的设计和实现:StandardServer
java
s6516654962 小时前
Makefile语法学习
java·linux·前端
Rabitebla2 小时前
二分查找(含有动画展示):不再写出死循环
java·开发语言
.柒宇.2 小时前
SpringCloud微服务入门教程
spring·spring cloud·微服务
人道领域2 小时前
【LeetCode刷题日记】150.逆波兰表达式求值
java·数据结构·算法·leetcode