🍃 Spring 中的模式
框架源码里用了哪些设计模式?——必背清单
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 两题都拿分