Spring框架運用了多種設計模式方式
Spring 框架在設計和實現(xiàn)過程中,廣泛運用了多種設計模式,這些設計模式幫助 Spring 實現(xiàn)了高內(nèi)聚、低耦合、可擴展和易維護的架構。
以下詳細介紹 Spring 中常用的設計模式及其應用場景:
1. 工廠模式(Factory Pattern)
作用:封裝對象創(chuàng)建的邏輯,解耦對象的創(chuàng)建和使用,讓代碼更靈活、可維護。
Spring 中的體現(xiàn):
BeanFactory 和 ApplicationContext:
它們是工廠模式的典型實現(xiàn),負責創(chuàng)建和管理 Bean。
BeanFactory是基礎工廠接口,提供最基本的 Bean 創(chuàng)建、查找功能;ApplicationContext是更高級的工廠(繼承BeanFactory),還支持 AOP、國際化、事件發(fā)布等功能。- 示例:通過
applicationContext.getBean("userService")獲取 Bean,無需關心UserService如何實例化(構造器、工廠方法等)。
FactoryBean:
- 是一種“工廠 Bean”,允許自定義 Bean 的創(chuàng)建邏輯。
- 比如整合第三方框架(如 MyBatis 的
SqlSessionFactoryBean)時,FactoryBean可以封裝復雜的創(chuàng)建過程,讓框架無縫接入 Spring。
2. 單例模式(Singleton Pattern)
作用:保證一個類僅有一個實例,并提供全局訪問點,節(jié)省資源、保證狀態(tài)一致。
Spring 中的體現(xiàn):
默認 Bean 作用域(singleton):
Spring 容器中,默認情況下每個 Bean 的作用域是單例(除非顯式配置 prototype 或其他作用域)。
- 實現(xiàn):通過
DefaultSingletonBeanRegistry維護一個單例緩存(singletonObjects),確保 Bean 全局唯一。 - 示例:
@Service標注的服務類,整個應用中只有一個實例,避免重復創(chuàng)建開銷。
3. 代理模式(Proxy Pattern)
作用:通過代理對象增強目標對象的功能(如權限控制、日志、事務),且不修改目標對象代碼。
Spring 中的體現(xiàn):
AOP 實現(xiàn):
Spring AOP 基于動態(tài)代理,有兩種方式:
- JDK 動態(tài)代理:針對實現(xiàn)接口的類,通過
java.lang.reflect.Proxy創(chuàng)建代理對象,增強接口方法。 - CGLIB 動態(tài)代理:針對未實現(xiàn)接口的類,通過繼承目標類創(chuàng)建代理對象(重寫方法實現(xiàn)增強)。
示例:@Transactional 注解的事務管理,就是通過代理對象在方法調(diào)用前后織入事務邏輯。
4. 模板方法模式(Template Method Pattern)
作用:定義算法的骨架,將可變部分延遲到子類實現(xiàn),減少重復代碼。
Spring 中的體現(xiàn):
- 數(shù)據(jù)庫操作模板(
JdbcTemplate、RedisTemplate等): - 以
JdbcTemplate為例,它封裝了 JDBC 的固定流程(獲取連接、創(chuàng)建語句、執(zhí)行 SQL、關閉資源),而 SQL 執(zhí)行邏輯(可變部分)由開發(fā)者通過回調(diào)(RowMapper)實現(xiàn)。
示例:
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)
作用:定義對象間的一對多依賴,當一個對象狀態(tài)變化時,通知所有依賴對象自動更新。
Spring 中的體現(xiàn):
事件驅動模型(ApplicationEvent 和 ApplicationListener):
- 發(fā)布者通過
ApplicationEventPublisher發(fā)布事件(如ContextRefreshedEvent表示容器初始化完成); - 監(jiān)聽者實現(xiàn)
ApplicationListener接口,訂閱感興趣的事件,事件發(fā)生時觸發(fā)onApplicationEvent方法。
示例:
// 自定義事件
public class UserRegisteredEvent extends ApplicationEvent {
public UserRegisteredEvent(User user) {
super(user);
}
}
// 監(jiān)聽者
@Component
public class UserRegisteredListener implements ApplicationListener<UserRegisteredEvent> {
@Override
public void onApplicationEvent(UserRegisteredEvent event) {
User user = (User) event.getSource();
// 發(fā)送注冊通知(如郵件、短信)
}
}
// 發(fā)布事件
@Service
public class UserService {
@Autowired private ApplicationEventPublisher publisher;
public void register(User user) {
// 注冊邏輯...
publisher.publishEvent(new UserRegisteredEvent(user));
}
}
6. 適配器模式(Adapter Pattern)
作用:將一個類的接口轉換成客戶端期望的另一種接口,使原本不兼容的類可以協(xié)作。
Spring 中的體現(xiàn):
HandlerAdapter(Spring MVC 中):
DispatcherServlet 需要調(diào)用不同類型的 Controller(如注解驅動的 @Controller、古老的 Controller 接口),HandlerAdapter 作為適配器,統(tǒng)一調(diào)用方式。
示例:
SimpleControllerHandlerAdapter適配實現(xiàn)Controller接口的類;RequestMappingHandlerAdapter適配@Controller+@RequestMapping注解的類。- 這樣
DispatcherServlet只需調(diào)用handlerAdapter.handle(...),無需關心具體 Controller 類型。
7. 裝飾者模式(Decorator Pattern)
作用:動態(tài)地給對象添加額外職責,比繼承更靈活(避免子類爆炸)。
Spring 中的體現(xiàn):
BeanWrapper 對 Bean 的增強:
BeanWrapper封裝了 Bean 對象,并提供類型轉換、屬性訪問等增強功能。- 比如在屬性注入時,
BeanWrapper會自動將配置文件中的字符串轉換為 Bean 的屬性類型(如把"18"轉為Integer)。
HttpServletRequestWrapper(Spring Web 中):
- 用于包裝
HttpServletRequest,動態(tài)添加功能(如修改請求參數(shù)、頭信息)。
8. 策略模式(Strategy Pattern)
作用:定義一系列算法,將每個算法封裝成策略類,運行時動態(tài)選擇策略。
Spring 中的體現(xiàn):
資源加載策略(ResourceLoader):
Spring 支持多種資源加載方式(如類路徑、文件系統(tǒng)、URL),ResourceLoader 通過 Resource 接口的不同實現(xiàn)(ClassPathResource、FileSystemResource 等),動態(tài)選擇加載策略。
示例:
Resource resource = resourceLoader.getResource("classpath:config.properties");
// 根據(jù)路徑前綴(classpath:、file: 等)自動選擇策略加載資源
總結:Spring 設計模式的價值
這些設計模式不是孤立的,而是相互配合,共同支撐 Spring 的核心特性(如 IoC、AOP、MVC):
- 解耦與靈活:工廠模式、代理模式、適配器模式讓組件可插拔、易擴展;
- 高效與簡潔:模板方法模式、單例模式減少重復代碼,提升性能;
- 可維護與可擴展:觀察者模式、策略模式讓框架具備高內(nèi)聚、低耦合的架構。
理解這些設計模式,不僅能更好地使用 Spring,還能學習框架設計的思路,應用到自己的代碼中。
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
SpringBoot整合DeepSeek技術指南(實際應用場景)
這篇文章主要介紹了SpringBoot整合DeepSeek技術指南,本文通過實際應用場景模擬給大家介紹的非常詳細,感興趣的朋友一起看看吧2025-04-04
淺談Spring Data如何簡化數(shù)據(jù)操作的方法
這篇文章主要介紹了看Spring Data如何簡化數(shù)據(jù)操作的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-04-04
Java getParameter()獲取數(shù)據(jù)為空的問題
這篇文章主要介紹了Java getParameter()獲取數(shù)據(jù)為空的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-03-03
聊聊SpringCloud中的Ribbon進行服務調(diào)用的問題
SpringCloud-Ribbon是基于Netflix?Ribbon實現(xiàn)的一套客戶端負載均衡的工具。本文給大家介紹SpringCloud中的Ribbon進行服務調(diào)用的問題,感興趣的朋友跟隨小編一起看看吧2022-01-01

