网站首页 > java教程 正文
设计模式是框架设计的 “灵魂”,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<>();
@Override
public 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. 缓存单例Bean
if (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) {
// 链式调用构建复杂的BeanDefinition
BeanDefinition 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 {
@Override
public void save() {
System.out.println("执行save方法");
}
}
// 切面逻辑:方法执行前后打印日志
public class LogAdvice implements MethodInterceptor {
@Override
public 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 {
@Override
public boolean supports(Object handler) {
// 支持带@RequestMapping的控制器
return handler instanceof HandlerMethod && hasRequestMappingAnnotation((HandlerMethod) handler);
}
@Override
public 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 {
@Override
public boolean supports(Object handler) {
return handler instanceof HttpRequestHandler;
}
@Override
public 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;
}
// 默认调用原始对象的方法
@Override
public 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 {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// 装饰原始request,添加trim功能
HttpServletRequest wrappedRequest = new HttpServletRequestWrapper((HttpServletRequest) request) {
@Override
public 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创建的完整流程(固定)
@Override
public 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 {
@Override
protected 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> {
@Override
public 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 {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
System.out.println("请求URL:" + request.getRequestURI());
return true; // 继续传递
}
}
// 权限拦截器
public class AuthInterceptor implements HandlerInterceptor {
@Override
public 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 或其他框架时,不必刻意套用所有模式,而是要理解 “模式是为了解决特定问题而存在”。当遇到 “如何解耦对象创建”“如何动态扩展功能” 等问题时,再选择合适的模式,才能真正发挥设计模式的威力。
- 上一篇: 工作中最常用的 8 种设计模式
- 下一篇:已经是最后一篇了
猜你喜欢
- 2025-08-05 工作中最常用的 8 种设计模式
- 2025-08-05 一文读懂设计模式,看这篇就够了
- 2025-08-05 java设计模式之责任链模式
- 2025-08-05 从复杂到优雅:用建造者和责任链重塑代码架构
- 2025-08-05 带你读Effective系列:创建对象-Builder构建器
- 2025-08-05 面试官:JDK中都用了哪些设计模式?
- 2025-08-05 工厂、建造者、装饰器、适配器:解密JDK设计模式的实战妙用
- 2025-08-05 一天一个设计模式(五):建造者模式,构建优美的Java对象
- 2025-08-05 设计模式——浅谈模板方法模式与建造者模式的异同
- 2025-08-05 JAVA建造模式的适用场景,优缺点你知道吗,这篇文章彻底讲透
你 发表评论:
欢迎- 08-05深入理解 Spring 设计模式:从实现原理到思想精髓
- 08-05工作中最常用的 8 种设计模式
- 08-05一文读懂设计模式,看这篇就够了
- 08-05java设计模式之责任链模式
- 08-05从复杂到优雅:用建造者和责任链重塑代码架构
- 08-05带你读Effective系列:创建对象-Builder构建器
- 08-05面试官:JDK中都用了哪些设计模式?
- 08-05工厂、建造者、装饰器、适配器:解密JDK设计模式的实战妙用
- 最近发表
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)