Skip to content

Spring 中的设计模式

  Spring 源码中大量使用了经典设计模式,理解这些模式能帮你读懂 Spring 源码,也能让你写出更优雅的代码。

一、单例模式(Singleton)

Spring 默认的 Bean 作用域就是单例:

  @Component
  public class OrderService { }
  // 整个容器只有一个 OrderService 实例

  实现方式:三级缓存(singletonObjects)
  DefaultSingletonBeanRegistry.singletonObjects  → ConcurrentHashMap<String, Object>
java
// Spring 单例注册表(简化)
public class DefaultSingletonBeanRegistry {
    // 一级缓存:完全初始化的单例 Bean
    private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
}

二、工厂模式(Factory)

Spring 的 BeanFactory 是工厂模式的典型应用:

  BeanFactory(工厂接口)

  ApplicationContext(扩展的工厂接口)

  ClassPathXmlApplicationContext / AnnotationConfigApplicationContext(具体工厂)

  // 使用
  BeanFactory factory = new AnnotationConfigApplicationContext(AppConfig.class);
  OrderService service = factory.getBean(OrderService.class);  // 工厂生产 Bean
java
// FactoryBean:自定义工厂,用于创建复杂 Bean
@Component
public class MyBatisSqlSessionFactoryBean implements FactoryBean<SqlSessionFactory> {

    @Override
    public SqlSessionFactory getObject() throws Exception {
        // 复杂的创建逻辑
        return new SqlSessionFactoryBuilder().build(configuration);
    }

    @Override
    public Class<?> getObjectType() {
        return SqlSessionFactory.class;
    }
}

三、模板方法模式(Template Method)

JdbcTemplate、RestTemplate、RedisTemplate 都是模板方法模式:

  JdbcTemplate:
    // 固定步骤:获取连接 → 执行 SQL → 处理结果 → 关闭连接
    // 可变部分:SQL 语句和结果处理(由调用者提供)

  jdbcTemplate.query("SELECT * FROM users", (rs, rowNum) -> {
      // 用户只需要关心结果集映射,连接管理由 JdbcTemplate 处理
      return new User(rs.getLong("id"), rs.getString("name"));
  });

四、代理模式(Proxy)

AOP 的核心就是代理模式:

  JDK 动态代理:
    目标类有接口 → 创建实现同一接口的代理对象

  CGLIB 代理:
    目标类无接口 → 创建目标类的子类代理对象

  @Transactional、@Async、@Cacheable 都依赖代理模式

五、观察者模式(Observer)

Spring 事件机制就是观察者模式:

  发布者(Subject):ApplicationEventPublisher
  观察者(Observer):@EventListener 标注的方法
  事件(Event):ApplicationEvent 子类

  publisher.publishEvent(event)  → 通知所有注册的监听器

六、策略模式(Strategy)

Spring 中策略模式的应用:

  // 资源加载策略
  ResourceLoader
    ├── DefaultResourceLoader(默认策略:classpath)
    ├── FileSystemResourceLoader(文件系统策略)
    └── ServletContextResourceLoader(Web 环境策略)

  // 视图解析策略
  ViewResolver
    ├── InternalResourceViewResolver(JSP)
    ├── ThymeleafViewResolver(Thymeleaf)
    └── FreeMarkerViewResolver(FreeMarker)

七、适配器模式(Adapter)

Spring MVC 的 HandlerAdapter 就是适配器模式:

  DispatcherServlet 不关心 Controller 的具体形式,
  通过 HandlerAdapter 统一适配各种 Handler:

  HandlerAdapter
    ├── RequestMappingHandlerAdapter  → 适配 @RequestMapping 方法
    ├── HttpRequestHandlerAdapter     → 适配 HttpRequestHandler
    └── SimpleControllerHandlerAdapter → 适配 Controller 接口

八、装饰器模式(Decorator)

Spring 的 BeanDefinitionDecorator 和 ServerHttpRequestDecorator:

  // 对请求进行包装,增加额外功能
  ServerHttpRequestDecorator
    ├── 添加请求头
    ├── 修改请求体
    └── 日志记录

九、面试要点

Q1:Spring 中使用了哪些设计模式?

  单例模式(Bean 默认作用域)、工厂模式(BeanFactory)、模板方法模式(JdbcTemplate)、代理模式(AOP)、观察者模式(事件机制)、策略模式(ResourceLoader)、适配器模式(HandlerAdapter)、装饰器模式(BeanDefinitionDecorator)。

Q2:为什么要用工厂模式而不是直接 new?

  工厂模式将对象的创建和使用分离,便于管理对象的生命周期、依赖注入、AOP 增强。直接 new 的对象不受 Spring 管理,无法享受 IoC 和 AOP 的能力。

Q3:模板方法模式的核心思想?

  在父类中定义算法骨架(固定步骤),子类实现具体细节(可变部分)。JdbcTemplate 的骨架是"获取连接→执行 SQL→处理结果→关闭连接",结果集映射由调用者提供。