1. Spring 源码中的设计模式清单?

模式 Spring 中的应用
工厂模式BeanFactory:IoC 容器本身,按 BeanDefinition 创建并管理 Bean
FactoryBean:一种特殊的 Bean,getObject() 返回的才是真正要用的对象(如 MyBatis 的 MapperFactoryBean 生产 Mapper 代理)
两者是两个不同的接口,别混——这是高频题
单例模式容器默认 singleton 作用域(注册表单例)
代理模式AOP:JDK 动态代理 / CGLIB,@Transactional 拦截
模板方法AbstractApplicationContext.refresh()(启动骨架)、JdbcTemplate(execute() 定义骨架 + 回调接口)、RestTemplate
观察者/发布订阅ApplicationEvent 事件机制、@EventListener
适配器HandlerAdapter(统一多种 Controller)、MethodInvoker 适配
策略HandlerMapping/ViewResolver 多实现选择;ThreadPoolTaskExecutor 策略
责任链HandlerInterceptor 链、Filter 链、Spring Security FilterChain
装饰器BeanWrapper 增强、HttpRequestWrapper(ServletRequest 包装)
建造者BeanDefinitionBuilder、UriComponentsBuilder、SecurityHttpConfigurer
外观TransactionTemplate 等封装底层 API 的简化入口;JdbcTemplate 更准确的归属是模板方法(见上一行)
原型Spring 没有对应实现。注意 prototype 作用域只是「每次获取新建实例」,与 GoF 原型模式(克隆已有对象)同名不同义,不要拿来当原型模式的例子
组合CompositeCacheManager(多缓存管理器组合)

🎯 面试要点

  • 面试常问前六个:工厂(IoC)、代理(AOP)、模板方法(refresh)、观察者(事件)、适配器(HandlerAdapter)、策略(多实现选择)
  • 能举例到"类名"级别(AbstractApplicationContext.refresh())是深度分

2. refresh() 为什么是模板方法?(示例)

AbstractApplicationContext.refresh() 骨架
public void refresh() throws BeansException {
    synchronized (startupShutdownMonitor) {
        prepareRefresh();                        // ① 准备(钩子:子类可扩展)
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();  // ② 创建 BeanFactory
        prepareBeanFactory(beanFactory);         // ③ 配置(钩子)
        try {
            postProcessBeanFactory(beanFactory); // ④ 子类覆写点(模板方法)
            invokeBeanFactoryPostProcessors(...) // ⑤ 执行扩展点
            registerBeanPostProcessors(...);     // ⑥
            initMessageSource();                 // ⑦ 国际化
            initApplicationEventMulticaster();   // ⑧ 事件广播器
            onRefresh();                         // ⑨ 模板方法:子类(如 Spring Boot)在此初始化 Web 容器
            registerListeners();                 // ⑩
            finishBeanFactoryInitialization(...) // ⑪ 实例化所有单例 Bean(核心)
            finishRefresh();                     // ⑫ 发布 ContextRefreshedEvent
        }
        catch (BeansException ex) {
            destroyBeans(); cancelRefresh(ex); throw ex;
        }
    }
}

🎯 面试要点

  • 骨架固定(流程 12 步)、步骤可选覆写(onRefresh 等)——标准模板方法
  • Spring Boot 的 ServletWebServerApplicationContext 覆写 onRefresh 启动内嵌 Tomcat
  • 这条答出来,设计模式 + Spring 两题都拿分

🎤 常见面试追问

  1. Spring 里用了哪些设计模式?(背 5 个就够)——工厂(BeanFactory 创建 Bean)、单例(默认作用域)、代理(AOP)、模板方法(AbstractApplicationContext.refresh())、观察者(ApplicationEvent)、适配器(HandlerAdapter)、策略(多实现选择)、责任链(拦截器)。
  2. refresh() 为什么是模板方法?——12 步启动流程固定(骨架),其中 onRefresh() 等步骤留给子类覆写——Spring Boot 就是覆写 onRefresh 启动内嵌 Tomcat。
  3. HandlerAdapter 解决什么问题?——适配器:不同 Controller 类型(@Controller/HttpRequestHandler/函数式)统一成 DispatcherServlet 可调用的形态。
  4. Spring 事件是同步还是异步?——默认同步(同一线程);@Async + @EnableAsync 可异步(注意事务传播不过线程)。
  5. 单例模式在 Spring 里和 GoF 有什么不同?——Spring 是"容器级单例"(每个容器一个实例,不保证全局唯一),且通过注册表管理——不是 JVM 全局单例。

📖 名词解释(本页术语)

术语 大白话解释
refresh()ApplicationContext 的启动方法:创建 BeanFactory、注册 BeanPostProcessor、实例化单例 Bean、发布事件——12 步模板方法。
FactoryBean定制 Bean 创建逻辑的接口(getObject() 返回真正对象)——MyBatis 的 Mapper 代理就是它生产的。
ApplicationEventSpring 事件对象:publishEvent 发布,@EventListener 监听——观察者/发布订阅的应用。
HandlerAdapter适配器模式:统一调用不同类型的 Controller 方法。
HandlerMapping / ViewResolver策略模式的体现:多种实现可替换(按注解/按配置映射;多种视图解析器)。
容器级单例Spring 的默认作用域:每个 Spring 容器一个 Bean 实例(不是 JVM 全局)。
⚠️ 本页面由 AI 生成,内容仅供参考,请以官方文档和实际源码为准。