Spring框架运用了多种设计模式方式
作者:dj_master
Spring 框架在设计和实现过程中,广泛运用了多种设计模式,这些设计模式帮助 Spring 实现了高内聚、低耦合、可扩展和易维护的架构。
以下详细介绍 Spring 中常用的设计模式及其应用场景:
1. 工厂模式(Factory Pattern)
作用:封装对象创建的逻辑,解耦对象的创建和使用,让代码更灵活、可维护。
Spring 中的体现:
BeanFactory
和 ApplicationContext
:
它们是工厂模式的典型实现,负责创建和管理 Bean。
BeanFactory
是基础工厂接口,提供最基本的 Bean 创建、查找功能;ApplicationContext
是更高级的工厂(继承BeanFactory
),还支持 AOP、国际化、事件发布等功能。- 示例:通过
applicationContext.getBean("userService")
获取 Bean,无需关心UserService
如何实例化(构造器、工厂方法等)。
FactoryBean
:
- 是一种“工厂 Bean”,允许自定义 Bean 的创建逻辑。
- 比如整合第三方框架(如 MyBatis 的
SqlSessionFactoryBean
)时,FactoryBean
可以封装复杂的创建过程,让框架无缝接入 Spring。
2. 单例模式(Singleton Pattern)
作用:保证一个类仅有一个实例,并提供全局访问点,节省资源、保证状态一致。
Spring 中的体现:
默认 Bean 作用域(singleton
):
Spring 容器中,默认情况下每个 Bean 的作用域是单例(除非显式配置 prototype
或其他作用域)。
- 实现:通过
DefaultSingletonBeanRegistry
维护一个单例缓存(singletonObjects
),确保 Bean 全局唯一。 - 示例:
@Service
标注的服务类,整个应用中只有一个实例,避免重复创建开销。
3. 代理模式(Proxy Pattern)
作用:通过代理对象增强目标对象的功能(如权限控制、日志、事务),且不修改目标对象代码。
Spring 中的体现:
AOP 实现:
Spring AOP 基于动态代理,有两种方式:
- JDK 动态代理:针对实现接口的类,通过
java.lang.reflect.Proxy
创建代理对象,增强接口方法。 - CGLIB 动态代理:针对未实现接口的类,通过继承目标类创建代理对象(重写方法实现增强)。
示例:@Transactional
注解的事务管理,就是通过代理对象在方法调用前后织入事务逻辑。
4. 模板方法模式(Template Method Pattern)
作用:定义算法的骨架,将可变部分延迟到子类实现,减少重复代码。
Spring 中的体现:
- 数据库操作模板(
JdbcTemplate
、RedisTemplate
等): - 以
JdbcTemplate
为例,它封装了 JDBC 的固定流程(获取连接、创建语句、执行 SQL、关闭资源),而 SQL 执行逻辑(可变部分)由开发者通过回调(RowMapper
)实现。
示例:
List<User> users = jdbcTemplate.query("SELECT * FROM user", new RowMapper<User>() { @Override public User mapRow(ResultSet rs, int rowNum) throws SQLException { // 映射结果集到 User 对象(自定义逻辑) return new User(rs.getLong("id"), rs.getString("name")); } });
5. 观察者模式(Observer Pattern)
作用:定义对象间的一对多依赖,当一个对象状态变化时,通知所有依赖对象自动更新。
Spring 中的体现:
事件驱动模型(ApplicationEvent
和 ApplicationListener
):
- 发布者通过
ApplicationEventPublisher
发布事件(如ContextRefreshedEvent
表示容器初始化完成); - 监听者实现
ApplicationListener
接口,订阅感兴趣的事件,事件发生时触发onApplicationEvent
方法。
示例:
// 自定义事件 public class UserRegisteredEvent extends ApplicationEvent { public UserRegisteredEvent(User user) { super(user); } } // 监听者 @Component public class UserRegisteredListener implements ApplicationListener<UserRegisteredEvent> { @Override public void onApplicationEvent(UserRegisteredEvent event) { User user = (User) event.getSource(); // 发送注册通知(如邮件、短信) } } // 发布事件 @Service public class UserService { @Autowired private ApplicationEventPublisher publisher; public void register(User user) { // 注册逻辑... publisher.publishEvent(new UserRegisteredEvent(user)); } }
6. 适配器模式(Adapter Pattern)
作用:将一个类的接口转换成客户端期望的另一种接口,使原本不兼容的类可以协作。
Spring 中的体现:
HandlerAdapter
(Spring MVC 中):
DispatcherServlet
需要调用不同类型的 Controller(如注解驱动的 @Controller
、古老的 Controller
接口),HandlerAdapter
作为适配器,统一调用方式。
示例:
SimpleControllerHandlerAdapter
适配实现Controller
接口的类;RequestMappingHandlerAdapter
适配@Controller
+@RequestMapping
注解的类。- 这样
DispatcherServlet
只需调用handlerAdapter.handle(...)
,无需关心具体 Controller 类型。
7. 装饰者模式(Decorator Pattern)
作用:动态地给对象添加额外职责,比继承更灵活(避免子类爆炸)。
Spring 中的体现:
BeanWrapper
对 Bean 的增强:
BeanWrapper
封装了 Bean 对象,并提供类型转换、属性访问等增强功能。- 比如在属性注入时,
BeanWrapper
会自动将配置文件中的字符串转换为 Bean 的属性类型(如把"18"
转为Integer
)。
HttpServletRequestWrapper
(Spring Web 中):
- 用于包装
HttpServletRequest
,动态添加功能(如修改请求参数、头信息)。
8. 策略模式(Strategy Pattern)
作用:定义一系列算法,将每个算法封装成策略类,运行时动态选择策略。
Spring 中的体现:
资源加载策略(ResourceLoader
):
Spring 支持多种资源加载方式(如类路径、文件系统、URL),ResourceLoader
通过 Resource
接口的不同实现(ClassPathResource
、FileSystemResource
等),动态选择加载策略。
示例:
Resource resource = resourceLoader.getResource("classpath:config.properties"); // 根据路径前缀(classpath:、file: 等)自动选择策略加载资源
总结:Spring 设计模式的价值
这些设计模式不是孤立的,而是相互配合,共同支撑 Spring 的核心特性(如 IoC、AOP、MVC):
- 解耦与灵活:工厂模式、代理模式、适配器模式让组件可插拔、易扩展;
- 高效与简洁:模板方法模式、单例模式减少重复代码,提升性能;
- 可维护与可扩展:观察者模式、策略模式让框架具备高内聚、低耦合的架构。
理解这些设计模式,不仅能更好地使用 Spring,还能学习框架设计的思路,应用到自己的代码中。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。