五种高频设计模式及其在 Spring 中的应用揭秘
五种高频设计模式及其在 Spring 中的应用揭秘
1. 适配器模式(Adapter Pattern)
模式简介
适配器模式是一种结构型设计模式,通过将一个接口转换为客户端期望的另一个接口,使得原本不兼容的接口可以协同工作。它的核心作用在于兼容性适配,解决“老接口”和“新需求”的冲突。
模式结构
- 目标接口:客户端期望使用的接口。
- 适配器类:实现目标接口,并持有被适配者的引用,将被适配者的方法转换为目标接口的方法。
- 被适配者:需要适配的类,其接口与目标接口不兼容。
使用场景
- 将旧系统的接口适配到新系统中。
- 为现有类提供新接口。
- 统一多种接口,提供通用方法。
Java 示例代码
需求描述:将一种老式日志格式适配为新式格式。
// 目标接口:新日志格式
public interface NewLogger {
void log(String message);
}
// 被适配者:老式日志格式
public class OldLogger {
public void writeLog(String msg) {
System.out.println("Old Logger: " + msg);
}
}
// 适配器类:适配老式日志为新格式
public class LoggerAdapter implements NewLogger {
private final OldLogger oldLogger;
public LoggerAdapter(OldLogger oldLogger) {
this.oldLogger = oldLogger;
}
@Override
public void log(String message) {
oldLogger.writeLog(message); // 调用老式日志的实现
}
}
在 Spring 框架中的应用
Spring 的 HandlerAdapter
是适配器模式的经典实现,用于适配不同类型的控制器到统一的处理逻辑。例如:
SimpleControllerHandlerAdapter
:适配实现了Controller
接口的控制器。RequestMappingHandlerAdapter
:适配标注了@RequestMapping
的控制器方法。
核心代码:
public interface HandlerAdapter {
boolean supports(Object handler); // 检查适配器是否支持某个处理器
ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
}
通过适配器,Spring 能够支持多种控制器类型,提升框架的灵活性和扩展性。
2. 装饰器模式(Decorator Pattern)
模式简介
装饰器模式通过为对象动态地添加职责,而不是通过继承来扩展功能。它允许我们按照需求组合功能,从而实现高效的功能扩展。
模式结构
- 组件接口:定义核心功能。
- 具体组件:核心功能的实现类。
- 装饰器类:实现组件接口,并包含对核心组件的引用,用于动态扩展功能。
- 具体装饰器:实现特定扩展功能。
使用场景
- 动态为对象添加功能(如 I/O 流)。
- 需要在不改变原始类的前提下扩展功能。
Java 示例代码
需求描述:在发送通知前后添加日志功能。
// 抽象组件
public interface Notifier {
void send(String message);
}
// 具体组件:基本通知实现
public class EmailNotifier implements Notifier {
@Override
public void send(String message) {
System.out.println("发送邮件通知: " + message);
}
}
// 装饰器基类
public abstract class NotifierDecorator implements Notifier {
protected final Notifier notifier;
public NotifierDecorator(Notifier notifier) {
this.notifier = notifier;
}
}
// 具体装饰器:添加日志功能
public class LoggingNotifierDecorator extends NotifierDecorator {
public LoggingNotifierDecorator(Notifier notifier) {
super(notifier);
}
@Override
public void send(String message) {
System.out.println("日志:开始发送通知...");
notifier.send(message); // 调用被装饰对象的方法
System.out.println("日志:通知发送完毕!");
}
}
在 Spring 框架中的应用
Spring 中的 BeanPostProcessor
和 Spring Security
的过滤器链体现了装饰器模式:
-
BeanPostProcessor
:在 Bean 初始化前后动态添加行为。示例代码:
public class LoggingBeanPostProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("初始化前日志:" + beanName); return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("初始化后日志:" + beanName); return bean; } }
3. 观察者模式(Observer Pattern)
模式简介
观察者模式定义了一种一对多的依赖关系,当被观察对象的状态发生变化时,所有观察者会自动收到通知。它是事件驱动模型的基础。
模式结构
- 主题(Subject):被观察的对象,维护观察者列表。
- 观察者(Observer):需要被通知的对象。
- 具体主题和具体观察者:实现主题和观察者接口的类。
使用场景
- GUI 事件监听。
- 数据变化通知机制。
- 发布/订阅系统。
Java 示例代码
需求描述:实现一个简单的事件通知机制。
// 主题接口
public interface Subject {
void attach(Observer observer);
void detach(Observer observer);
void notifyObservers(String message);
}
// 观察者接口
public interface Observer {
void update(String message);
}
// 具体主题
public class NewsPublisher implements Subject {
private final List<Observer> observers = new ArrayList<>();
@Override
public void attach(Observer observer) {
observers.add(observer);
}
@Override
public void detach(Observer observer) {
observers.remove(observer);
}
@Override
public void notifyObservers(String message) {
for (Observer observer : observers) {
observer.update(message);
}
}
}
// 具体观察者
public class Subscriber implements Observer {
private final String name;
public Subscriber(String name) {
this.name = name;
}
@Override
public void update(String message) {
System.out.println(name + " 收到消息: " + message);
}
}
在 Spring 框架中的应用
Spring 的事件驱动模型基于观察者模式:
ApplicationEvent
:事件基类。ApplicationListener
:监听器接口。ApplicationEventPublisher
:事件发布器。
示例:
@Component
public class MyEventListener implements ApplicationListener<MyEvent> {
@Override
public void onApplicationEvent(MyEvent event) {
System.out.println("监听到事件: " + event.getMessage());
}
}
public class MyEvent extends ApplicationEvent {
private final String message;
public MyEvent(Object source, String message) {
super(source);
this.message = message;
}
public String getMessage() {
return message;
}
}
4. 构建者模式(Builder Pattern)
模式简介
构建者模式通过分步构建复杂对象,将对象创建过程与其表示分离,特别适用于构建复杂对象。
模式结构
- 产品(Product):要构建的复杂对象。
- 构建者(Builder):定义构建产品的方法。
- 具体构建者(ConcreteBuilder):实现构建过程。
- 指导者(Director):指导构建者构建产品。
Java 示例代码
// 产品类
public class Computer {
private String cpu;
private String gpu;
public static class Builder {
private String cpu;
private String gpu;
public Builder cpu(String cpu) {
this.cpu = cpu;
return this;
}
public Builder gpu(String gpu) {
this.gpu = gpu;
return this;
}
public Computer build() {
Computer computer = new Computer();
computer.cpu = this.cpu;
computer.gpu = this.gpu;
return computer;
}
}
}
在 Spring 框架中的应用
Spring 中的 BeanDefinitionBuilder
是构建者模式的典型应用,用于动态定义 Bean:
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(MyBean.class);
builder.addPropertyValue("name", "Spring");
builder.addPropertyValue("version", "5.x");
5. 责任链模式(Chain of Responsibility Pattern)
模式结构
- 处理者接口(Handler):定义处理请求的方法。
- 具体处理者(ConcreteHandler):实现处理逻辑,并决定是否将请求传递给下一个处理者。
- 责任链:由多个处理者组成,按照顺序处理请求。
使用场景
- 当多个对象都有可能处理同一请求时,将这些对象连成一条链,按顺序处理请求。
- 需要动态组合处理逻辑,但又不希望硬编码逻辑的顺序。
Java 示例代码
需求描述:一个日志处理系统,根据日志的级别分别由不同的处理者处理。
// 处理者接口
public abstract class LogHandler {
protected LogHandler nextHandler; // 下一个处理者
public void setNextHandler(LogHandler nextHandler) {
this.nextHandler = nextHandler;
}
public abstract void handle(String message, String level);
}
// 具体处理者:Debug日志处理
public class DebugLogHandler extends LogHandler {
@Override
public void handle(String message, String level) {
if ("DEBUG".equalsIgnoreCase(level)) {
System.out.println("DEBUG日志处理: " + message);
} else if (nextHandler != null) {
nextHandler.handle(message, level);
}
}
}
// 具体处理者:Error日志处理
public class ErrorLogHandler extends LogHandler {
@Override
public void handle(String message, String level) {
if ("ERROR".equalsIgnoreCase(level)) {
System.out.println("ERROR日志处理: " + message);
} else if (nextHandler != null) {
nextHandler.handle(message, level);
}
}
}
// 测试
public class LogHandlerTest {
public static void main(String[] args) {
// 创建处理链
LogHandler debugHandler = new DebugLogHandler();
LogHandler errorHandler = new ErrorLogHandler();
debugHandler.setNextHandler(errorHandler);
// 测试责任链
debugHandler.handle("系统调试信息", "DEBUG");
debugHandler.handle("系统错误信息", "ERROR");
debugHandler.handle("未知级别日志", "INFO"); // 无处理者
}
}
输出结果:
DEBUG日志处理: 系统调试信息
ERROR日志处理: 系统错误信息
在 Spring 框架中的应用
Spring 中责任链模式的应用非常广泛,以下是两个经典场景:
-
Spring Security 的过滤器链
- 在 Spring Security 中,
FilterChainProxy
管理着一系列的安全过滤器。每个过滤器完成特定的职责,例如认证、授权或日志记录。 - 这些过滤器按顺序组成责任链,当请求进入时,依次通过这些过滤器进行处理,直到过滤器链末端。
配置示例:
<http> <custom-filter position="FORM_LOGIN_FILTER" ref="myCustomFilter"/> </http>
代码实现:
public class MyCustomFilter extends GenericFilterBean { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // 在此处处理请求逻辑 System.out.println("自定义过滤器处理请求..."); chain.doFilter(request, response); // 传递给下一个过滤器 } }
- 在 Spring Security 中,
-
Spring MVC 的拦截器链
- Spring MVC 的
HandlerInterceptor
提供了一个类似责任链模式的机制,用于在请求处理的不同阶段添加逻辑,例如请求前的权限校验或请求后的日志记录。
示例代码:
public class MyInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("前置处理逻辑..."); return true; // 返回 false 则中断请求链 } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("后置处理逻辑..."); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("完成处理逻辑..."); } }
注册拦截器:
@Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new MyInterceptor()); } }
- Spring MVC 的
总结
通过本文,我们详细解读了五种常见设计模式在 Spring 框架中的应用:
- 适配器模式:用于将不同接口适配到统一接口(如 Spring 的
HandlerAdapter
)。 - 装饰器模式:动态扩展对象功能(如
BeanPostProcessor
)。 - 观察者模式:实现事件驱动机制(如
ApplicationListener
)。 - 构建者模式:构建复杂对象(如
BeanDefinitionBuilder
)。 - 责任链模式:组织多步骤处理(如 Spring Security 的过滤器链、Spring MVC 的拦截器链)。
设计模式在 Spring 中无处不在,理解并灵活运用这些模式,能够帮助开发者更深入地理解框架设计思想,并提升代码质量和系统的可维护性。建议在实际开发中多多关注框架源码中的设计模式应用,实践中不断提升自己的设计能力。