Spring 框架中的设计模式:从实现到思想的深度解析
设计模式是框架设计的 “灵魂”,Spring 作为 Java 生态中最成功的框架之一,其优雅性很大程度上源于对设计模式的灵活运用。在手写 mini-spring 框架的过程中,深入理解这些模式的应用场景和解决思路,不仅能帮助我们看懂框架源码,更能提升自己的架构设计能力。本文将结合实战案例,详解 Spring 中核心设计模式的实现与价值。
一、创建型模式:控制对象的创建逻辑
创建型模式专注于 “如何创建对象”,Spring 通过这些模式将对象的创建与使用解耦,这也是 IoC 容器的核心思想。
1. 工厂模式:IoC 容器的 “心脏”
核心问题:如何统一管理对象的创建过程,避免硬编码依赖?
Spring 中的实现:
Spring 的 IoC 容器本质是一个超级工厂,DefaultListableBeanFactory
作为核心工厂类,负责所有 Bean 的创建、管理和销毁。
// 简化的BeanFactory接口(工厂接口)
public interface BeanFactory {// 核心方法:获取Bean(生产对象)Object getBean(String name) throws BeansException;<T> T getBean(Class<T> requiredType) throws BeansException;
}// 核心实现类:DefaultListableBeanFactory
public class DefaultListableBeanFactory implements BeanFactory, BeanDefinitionRegistry {// 存储Bean定义(相当于“产品图纸”)private final Map<String, BeanDefinition> beanDefinitionMap = new HashMap<>();// 存储已创建的Bean(相当于“产品实例”)private final Map<String, Object> singletonObjects = new HashMap<>();@Overridepublic Object getBean(String name) {// 1. 检查缓存中是否已有实例(单例)Object bean = singletonObjects.get(name);if (bean != null) {return bean;}// 2. 从BeanDefinition中获取“创建图纸”BeanDefinition beanDefinition = beanDefinitionMap.get(name);if (beanDefinition == null) {throw new NoSuchBeanDefinitionException(name);}// 3. 根据BeanDefinition创建Bean(核心逻辑)bean = createBean(beanDefinition);// 4. 缓存单例Beanif (beanDefinition.isSingleton()) {singletonObjects.put(name, bean);}return bean;}// 创建Bean的具体实现(模板方法,由子类扩展)protected Object createBean(BeanDefinition beanDefinition) {try {// 简化版:直接通过反射创建实例(实际包含依赖注入、初始化等步骤)Class<?> beanClass = beanDefinition.getBeanClass();return beanClass.getDeclaredConstructor().newInstance();} catch (Exception e) {throw new BeansException("Failed to create bean", e);}}
}
设计价值:
- 开发者无需手动
new
对象,只需通过getBean
从工厂获取,实现了 “控制反转”; - 工厂统一管理 Bean 的创建逻辑(如依赖注入、初始化),将复杂创建过程封装,简化上层使用;
- 扩展性强:通过实现
BeanFactory
接口,可自定义工厂逻辑(如XmlBeanFactory
从 XML 加载 Bean 定义)。
2. 单例模式:Bean 实例的 “唯一性” 保障
核心问题:如何确保某个对象在容器中只有一个实例,避免重复创建消耗资源?
Spring 中的实现:
Spring 的singleton
作用域默认使用单例模式,但并非简单的 “饿汉 / 懒汉式”,而是由BeanFactory
统一管理单例的生命周期:
public class DefaultListableBeanFactory {// 单例Bean缓存池:key=beanName,value=单例实例private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);// 正在创建中的单例Bean(解决循环依赖)private final Map<String, Object> singletonFactories = new HashMap<>(16);// 获取单例Bean的核心逻辑protected Object getSingleton(String beanName) {// 1. 先从缓存中取Object singletonObject = singletonObjects.get(beanName);if (singletonObject == null) {// 2. 标记为“正在创建”(避免并发创建)synchronized (this.singletonObjects) {singletonObject = singletonObjects.get(beanName);if (singletonObject == null) {// 3. 调用创建逻辑(由子类实现)singletonObject = createBean(beanName);// 4. 放入缓存,标记为“已创建”singletonObjects.put(beanName, singletonObject);}}}return singletonObject;}
}
与传统单例的区别:
- 传统单例模式将实例控制逻辑硬编码在类内部(如私有构造器),而 Spring 将单例管理交给容器,类本身无需关心单例实现;
- 支持 “延迟初始化”(默认)和 “提前初始化”(
lazy-init=false
),灵活度更高; - 结合
singletonFactories
解决了循环依赖问题(如 A 依赖 B,B 依赖 A 时,通过工厂提前暴露半成品实例)。
3. 建造者模式:复杂对象的 “分步构建”
核心问题:如何简化复杂对象的创建过程(如包含多个属性、嵌套结构的对象)?
Spring 中的实现:
BeanDefinitionBuilder
用于构建BeanDefinition
(Bean 的元数据),BeanDefinition
包含类名、作用域、依赖等多个属性,建造者模式让构建过程更清晰:
// 复杂对象:BeanDefinition
public class BeanDefinition {private Class<?> beanClass;private String scope = "singleton";private boolean lazyInit = false;private ConstructorArgumentValues constructorArgumentValues; // 构造器参数private MutablePropertyValues propertyValues; // 属性值// 省略getter/setter
}// 建造者类:BeanDefinitionBuilder
public class BeanDefinitionBuilder {// 持有目标对象private final BeanDefinition beanDefinition;// 私有构造器,通过静态方法创建建造者private BeanDefinitionBuilder(Class<?> beanClass) {this.beanDefinition = new BeanDefinition();this.beanDefinition.setBeanClass(beanClass);}// 静态工厂方法:创建建造者public static BeanDefinitionBuilder genericBeanDefinition(Class<?> beanClass) {return new BeanDefinitionBuilder(beanClass);}// 分步设置属性public BeanDefinitionBuilder setScope(String scope) {this.beanDefinition.setScope(scope);return this; // 链式调用}public BeanDefinitionBuilder setLazyInit(boolean lazyInit) {this.beanDefinition.setLazyInit(lazyInit);return this;}public BeanDefinitionBuilder addPropertyValue(String name, Object value) {this.beanDefinition.getPropertyValues().add(name, value);return this;}// 构建最终对象public BeanDefinition getBeanDefinition() {return this.beanDefinition;}
}// 使用示例
public class BuilderTest {public static void main(String[] args) {// 链式调用构建复杂的BeanDefinitionBeanDefinition bd = BeanDefinitionBuilder.genericBeanDefinition(UserService.class).setScope("prototype").setLazyInit(true).addPropertyValue("userDao", new RefBeanDefinition("userDao")).getBeanDefinition();}
}
设计价值:
- 将复杂对象的构建步骤拆分,通过链式调用简化代码,提高可读性;
- 隐藏
BeanDefinition
的内部结构,避免直接操作其属性导致的错误; - 便于扩展:如需新增属性,只需在建造者中添加对应方法,无需修改使用方。
二、结构型模式:优化对象的组合与交互
结构型模式关注 “对象如何组合”,Spring 通过这些模式实现了功能的灵活扩展和模块解耦。
1. 代理模式:AOP 的 “灵魂实现”
核心问题:如何在不修改原有代码的情况下,为方法添加额外功能(如日志、事务)?
Spring 中的实现:
AOP(面向切面编程)通过代理模式实现,Spring 支持 JDK 动态代理(基于接口)和 CGLIB 代理(基于类):
// 目标接口
public interface UserService {void save();
}// 目标实现类
public class UserServiceImpl implements UserService {@Overridepublic void save() {System.out.println("执行save方法");}
}// 切面逻辑:方法执行前后打印日志
public class LogAdvice implements MethodInterceptor {@Overridepublic Object invoke(MethodInvocation invocation) throws Throwable {// 前置增强System.out.println("方法执行前:" + invocation.getMethod().getName());// 执行目标方法Object result = invocation.proceed();// 后置增强System.out.println("方法执行后:" + invocation.getMethod().getName());return result;}
}// 代理工厂:创建代理对象
public class ProxyFactory {public static Object createProxy(Object target, MethodInterceptor advice) {// JDK动态代理(仅支持接口)return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),(proxy, method, args) -> {// 调用切面逻辑return advice.invoke(new ReflectiveMethodInvocation(target, method, args));});}// 测试public static void main(String[] args) {UserService target = new UserServiceImpl();// 创建代理对象(织入切面)UserService proxy = (UserService) ProxyFactory.createProxy(target, new LogAdvice());// 调用代理对象的方法proxy.save();}
}
设计价值:
- 实现了 “横切逻辑”(如日志、事务)与 “业务逻辑” 的解耦,无需修改业务代码;
- 支持动态扩展:通过添加新的切面,可在不影响原有功能的情况下新增功能;
- 灵活性高:可根据目标对象是否有接口自动选择 JDK 或 CGLIB 代理。
2. 适配器模式:接口适配的 “万能转换头”
核心问题:如何让接口不兼容的类能够一起工作?
Spring 中的实现:
Spring MVC 的HandlerAdapter
是适配器模式的典型应用。MVC 中存在多种处理器(Controller
),如@RequestMapping
注解的控制器、HttpRequestHandler
等,HandlerAdapter
适配不同处理器,让DispatcherServlet
无需关心具体类型:
// 适配器接口
public interface HandlerAdapter {// 判断是否支持当前处理器boolean supports(Object handler);// 执行处理器逻辑ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
}// 适配@RequestMapping注解的控制器
public class RequestMappingHandlerAdapter implements HandlerAdapter {@Overridepublic boolean supports(Object handler) {// 支持带@RequestMapping的控制器return handler instanceof HandlerMethod && hasRequestMappingAnnotation((HandlerMethod) handler);}@Overridepublic ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) {// 调用注解控制器的方法(简化逻辑)HandlerMethod handlerMethod = (HandlerMethod) handler;Object result = handlerMethod.invoke();return new ModelAndView(result.toString());}
}// 适配HttpRequestHandler
public class HttpRequestHandlerAdapter implements HandlerAdapter {@Overridepublic boolean supports(Object handler) {return handler instanceof HttpRequestHandler;}@Overridepublic ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {((HttpRequestHandler) handler).handleRequest(request, response);return null; // 无视图返回}
}// DispatcherServlet中使用适配器
public class DispatcherServlet {private List<HandlerAdapter> handlerAdapters;protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {// 1. 找到对应的处理器(如Controller)Object handler = getHandler(request);// 2. 找到支持该处理器的适配器HandlerAdapter adapter = getHandlerAdapter(handler);// 3. 通过适配器执行处理器逻辑ModelAndView mv = adapter.handle(request, response, handler);// 渲染视图...}
}
设计价值:
- 隔离了
DispatcherServlet
与具体处理器的耦合,DispatcherServlet
只需调用适配器的handle
方法,无需关心处理器类型; - 便于扩展:新增处理器类型时,只需添加对应的适配器,无需修改
DispatcherServlet
源码(符合开闭原则)。
3. 装饰器模式:功能增强的 “灵活包装”
核心问题:如何在不修改原有对象的情况下,动态增强其功能?
Spring 中的实现:
HttpServletRequestWrapper
和HttpServletResponseWrapper
通过装饰器模式增强请求和响应对象:
// 原始接口
public interface HttpServletRequest {String getParameter(String name);// 其他方法...
}// 装饰器类(实现相同接口,持有原始对象)
public class HttpServletRequestWrapper implements HttpServletRequest {private final HttpServletRequest request;public HttpServletRequestWrapper(HttpServletRequest request) {this.request = request;}// 默认调用原始对象的方法@Overridepublic String getParameter(String name) {return request.getParameter(name);}// 可重写方法实现增强public String getParameterWithTrim(String name) {String value = request.getParameter(name);return value != null ? value.trim() : null;}
}// 使用示例:增强参数处理
public class TrimParameterFilter implements Filter {@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {// 装饰原始request,添加trim功能HttpServletRequest wrappedRequest = new HttpServletRequestWrapper((HttpServletRequest) request) {@Overridepublic String getParameter(String name) {String value = super.getParameter(name);return value != null ? value.trim() : null;}};// 传递装饰后的对象chain.doFilter(wrappedRequest, response);}
}
设计价值:
- 无需修改原始类(如
HttpServletRequest
的实现),通过包装实现功能增强; - 支持多层装饰:可通过多个装饰器叠加增强功能(如先 trim 参数,再过滤 XSS 攻击);
- 灵活性高:根据需要动态选择是否增强、增强哪些功能。
三、行为型模式:规范对象的交互行为
行为型模式关注 “对象如何交互”,Spring 通过这些模式实现了框架的流程控制和行为扩展。
1. 模板方法模式:固定流程的 “骨架定义”
核心问题:如何定义一个流程的骨架,将可变步骤延迟到子类实现?
Spring 中的实现:
AbstractBeanFactory
定义了 Bean 创建的流程骨架,子类只需实现特定步骤:
// 抽象模板类
public abstract class AbstractBeanFactory implements BeanFactory {// 模板方法:定义Bean创建的完整流程(固定)@Overridepublic final Object getBean(String name) throws BeansException {// 1. 检查缓存Object bean = getSingleton(name);if (bean != null) {return bean;}// 2. 获取Bean定义BeanDefinition bd = getBeanDefinition(name);// 3. 创建Bean(抽象方法,由子类实现)bean = createBean(name, bd);// 4. 初始化Bean(钩子方法,可选实现)bean = initializeBean(name, bean, bd);// 5. 放入缓存registerSingleton(name, bean);return bean;}// 抽象方法:创建Bean的具体逻辑(由子类实现)protected abstract Object createBean(String name, BeanDefinition bd) throws BeansException;// 钩子方法:初始化Bean(子类可覆盖)protected Object initializeBean(String name, Object bean, BeanDefinition bd) {// 默认空实现,子类可添加初始化逻辑(如调用init-method)return bean;}// 其他方法...
}// 子类实现:具体创建Bean的逻辑
public class DefaultListableBeanFactory extends AbstractBeanFactory {@Overrideprotected Object createBean(String name, BeanDefinition bd) throws BeansException {try {// 具体创建逻辑(如依赖注入)Object bean = bd.getBeanClass().newInstance();populateBean(bean, bd); // 填充属性return bean;} catch (Exception e) {throw new BeansException("创建Bean失败", e);}}
}
设计价值:
- 固定核心流程(如
getBean
的步骤),确保框架行为的一致性; - 可变步骤(如
createBean
)由子类实现,既保证了灵活性,又避免了流程逻辑的重复; - 钩子方法(如
initializeBean
)允许子类在特定节点添加自定义逻辑,无需修改模板方法。
2. 观察者模式:事件驱动的 “松耦合通信”
核心问题:如何实现组件间的 “发布 - 订阅” 通信,避免直接依赖?
Spring 中的实现:
Spring 的事件机制基于观察者模式,通过ApplicationEvent
(事件)、ApplicationListener
(观察者)和ApplicationEventMulticaster
(事件发布器)实现:
// 事件基类
public abstract class ApplicationEvent {private final Object source;private final long timestamp;public ApplicationEvent(Object source) {this.source = source;this.timestamp = System.currentTimeMillis();}// getter...
}// 自定义事件:用户注册事件
public class UserRegisteredEvent extends ApplicationEvent {private final String username;public UserRegisteredEvent(Object source, String username) {super(source);this.username = username;}// getter...
}// 观察者接口
public interface ApplicationListener<E extends ApplicationEvent> {void onApplicationEvent(E event);
}// 事件发布器
public class SimpleApplicationEventMulticaster {// 存储所有观察者private final Set<ApplicationListener<?>> listeners = new LinkedHashSet<>();// 注册观察者public void addApplicationListener(ApplicationListener<?> listener) {listeners.add(listener);}// 发布事件(通知所有观察者)public void multicastEvent(ApplicationEvent event) {for (ApplicationListener<?> listener : listeners) {// 检查观察者是否支持该事件if (supportsEvent(listener, event)) {((ApplicationListener<ApplicationEvent>) listener).onApplicationEvent(event);}}}private boolean supportsEvent(ApplicationListener<?> listener, ApplicationEvent event) {// 简化逻辑:通过泛型判断return true;}
}// 使用示例
public class UserService {private final SimpleApplicationEventMulticaster eventMulticaster;public UserService(SimpleApplicationEventMulticaster multicaster) {this.eventMulticaster = multicaster;}public void register(String username) {// 业务逻辑:注册用户System.out.println("用户注册:" + username);// 发布事件eventMulticaster.multicastEvent(new UserRegisteredEvent(this, username));}
}// 观察者:发送欢迎邮件
public class EmailListener implements ApplicationListener<UserRegisteredEvent> {@Overridepublic void onApplicationEvent(UserRegisteredEvent event) {System.out.println("发送欢迎邮件给:" + event.getUsername());}
}
设计价值:
- 实现了组件间的解耦:
UserService
发布事件后无需关心谁处理,观察者只需订阅事件即可; - 支持动态扩展:新增功能(如注册后发送短信)只需添加新的观察者,无需修改
UserService
; - 符合 “开闭原则”:对扩展开放(新增观察者),对修改关闭(不修改发布者)。
3. 责任链模式:请求处理的 “流水线作业”
核心问题:如何让多个处理器按顺序处理请求,且每个处理器可决定是否继续传递请求?
Spring 中的实现:
Spring MVC 的拦截器链(HandlerInterceptor
)通过责任链模式处理请求:
// 拦截器接口(责任链节点)
public interface HandlerInterceptor {// 前置处理:返回true则继续传递,false则中断boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;// 后置处理void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView mv) throws Exception;
}// 日志拦截器
public class LogInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {System.out.println("请求URL:" + request.getRequestURI());return true; // 继续传递}
}// 权限拦截器
public class AuthInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {String token = request.getHeader("token");if (token == null || "".equals(token)) {response.sendError(401, "未授权");return false; // 中断传递}return true; // 继续传递}
}// 责任链管理器
public class HandlerExecutionChain {private final Object handler; // 目标处理器private final List<HandlerInterceptor> interceptors = new ArrayList<>();public HandlerExecutionChain(Object handler) {this.handler = handler;}public void addInterceptor(HandlerInterceptor interceptor) {interceptors.add(interceptor);}// 执行前置拦截器链public boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {// 按顺序执行所有拦截器for (HandlerInterceptor interceptor : interceptors) {if (!interceptor.preHandle(request, response, handler)) {// 若拦截器返回false,中断链return false;}}return true;}
}// DispatcherServlet中使用责任链
public class DispatcherServlet {protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {// 获取处理器和拦截器链HandlerExecutionChain chain = getHandlerChain(request);// 执行前置拦截器if (!chain.applyPreHandle(request, response)) {return; // 被拦截,直接返回}// 执行处理器ModelAndView mv = handleRequest(request, response, chain.getHandler());// 执行后置拦截器...}
}
设计价值:
- 实现了请求处理的 “流水线化”,每个拦截器专注于单一职责(如日志、权限);
- 拦截器顺序可动态调整,且可随时新增 / 移除拦截器,灵活性高;
- 避免了请求发送者与多个处理器的直接耦合,符合迪米特法则。
四、总结:设计模式在 Spring 中的核心价值
Spring 框架的成功,离不开对设计模式的 “恰到好处” 的运用:
- 创建型模式(工厂、单例、建造者)解决了 “对象创建” 的问题,实现了 IoC 容器的核心能力;
- 结构型模式(代理、适配器、装饰器)解决了 “功能扩展” 的问题,让 AOP、MVC 等模块灵活且可扩展;
- 行为型模式(模板方法、观察者、责任链)解决了 “流程控制” 的问题,规范了框架的执行逻辑。
这些模式的价值不仅在于 “解决问题”,更在于提供了一套 “设计语言”—— 让框架的代码结构清晰、逻辑可预测,同时降低了开发者的学习成本(掌握模式后,很容易理解 Spring 的设计思路)。
在手写 mini-spring 或其他框架时,不必刻意套用所有模式,而是要理解 “模式是为了解决特定问题而存在”。当遇到 “如何解耦对象创建”“如何动态扩展功能” 等问题时,再选择合适的模式,才能真正发挥设计模式的威力。
如果这篇文章对大家有帮助可以点赞关注,你的支持就是我的动力😊!