」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > Singleton 和原型 Spring Bean 範圍:詳細探索

Singleton 和原型 Spring Bean 範圍:詳細探索

發佈於2024-11-06
瀏覽:790

Singleton and Prototype Spring Bean Scopes: A Detailed Exploration

当我第一次开始使用 Spring 时,最让我感兴趣的概念之一是 bean 范围的想法。 Spring 提供了各种 bean 作用域,用于确定在 Spring 容器内创建的 bean 的生命周期。最常用的两个范围是 Singleton 和 Prototype。了解这些范围对于设计高效且有效的 Spring 应用程序至关重要,所以让我带您了解我对它们的了解。

了解 Spring Bean 范围

在Spring中,bean是一个由Spring IoC(控制反转)容器实例化、组装和管理的对象。 Bean 作用域是指 bean 的生命周期 - 创建 bean 实例的方式和时间,以及它们的持续时间。

Spring 提供了几个 bean 作用域,但我将重点关注的两个是:

  • 单例作用域
  • 原型范围

每个范围都有其特定的用例,选择正确的范围可以显着影响应用程序的行为和性能。

单例范围

Singleton 作用域是 Spring 中的默认作用域,也是我最常使用的作用域。当使用 Singleton 范围定义一个 bean 时,这意味着 Spring 容器将仅创建该 bean 的一个实例,并且该单个实例将在整个应用程序上下文中共享。

它是如何运作的

当我将一个 bean 声明为 Singleton 时,Spring 在第一次请求时(在应用程序上下文启动期间或首次引用它时)创建该 bean 实例。之后,对该 bean 的每个后续请求都将返回相同的实例。

这是一个简单的例子:

@Configuration
public class AppConfig {
    @Bean
    public MyService myService() {
        return new MyService();
    }
}

在此示例中,myService() 是一个 Singleton bean。每次我从 Spring 上下文请求 MyService bean 时,我都会得到相同的实例。

Singleton Bean 的用例

我发现 Singleton 作用域非常适合无状态 Bean——那些不保存任何客户端特定信息的 Bean。示例包括:

  • 服务类:通常,这些类包含可以在应用程序之间共享的业务逻辑,而不需要单独的实例。
  • DAO 类:由于它们通常与数据库交互并且不维护特定于客户端的状态,因此单个实​​例就足够了。

优点和注意事项

Singleton beans 的主要优点是内存效率。通过重用单个实例,应用程序消耗更少的内存,并且创建和销毁对象的开销最小化。然而,对维护状态的 Singleton beans 保持谨慎是很重要的。如果 Singleton bean 无意中保存了状态(例如实例变量),则该状态可以在多个客户端之间共享,从而导致潜在的数据不一致。

原型范围

与 Singleton 相比,Prototype 范围在每次从 Spring 容器请求 bean 时都会创建一个新的 bean 实例。当我了解到这一点时,很明显 Prototype beans 对于每次使用都需要一个新实例的场景非常有用。

它是如何运作的

当使用 Prototype 作用域定义 bean 时,每次请求该 bean 时 Spring 都会返回一个新实例。以下是我定义 Prototype bean 的方式:

@Configuration
public class AppConfig {
    @Bean
    @Scope("prototype")
    public MyService myService() {
        return new MyService();
    }
}

在此示例中,每次我从 Spring 上下文请求 MyService bean 时,Spring 都会创建 MyService 的一个新实例。

原型 Bean 的用例

原型 bean 在处理有状态 bean 时特别有用——那些维护某种特定于客户端的状态或每次使用都需要唯一配置的 bean。一些典型的用例包括:

  • 命令对象:如果我要实现像 Command 这样的模式,其中每个命令单独执行并维护自己的状态,那么 Prototype bean 是正确的选择。
  • 会话或请求范围 Beans:在 Web 应用程序中,特定于用户会话或请求的 Bean 可以定义为原型,以确保为每个用户或请求创建一个新实例。

优点和注意事项

使用 Prototype beans 的主要优点是它在创建新实例时提供的灵活性。这在处理有状态对象时特别有用。然而,在性能和资源使用方面需要权衡。由于每次都会创建一个新实例,因此可能会导致更高的内存消耗和更频繁的垃圾收集。此外,与 Singleton bean 不同,Spring 不管理 Prototype bean 除了创建之外的生命周期,因此我必须手动处理这些 bean 的销毁和清理。

单例与原型:选择正确的范围

设计 Spring 应用程序时我面临的关键决策之一是在 Singleton 和 Prototype 范围之间进行选择。以下是我考虑的因素的总结:

  • 有状态:如果bean是无状态的,Singleton通常是最好的选择。对于有状态bean,Prototype 更合适。
  • 资源管理:单例 bean 的内存效率更高,因为只维护一个实例。原型 Bean 在提供更大灵活性的同时,也消耗更多资源。
  • 生命周期管理:单例 bean 在其整个生命周期中由 Spring 容器进行管理。相反,我必须管理 Prototype beans 的整个生命周期。

实际例子

让我提供一个实际场景,可能有助于阐明何时使用每个范围。假设我正在构建一个在线购物应用程序。

  • 购物车服务:该服务通常是无状态的,并且是 Singleton bean 的良好候选者。无需每次都创建新实例,同一个服务可以处理多个请求。
  • 订单处理:另一方面,代表客户订单的 Order 对象是有状态的,包含特定于该订单的详细信息。因此,它应该是一个 Prototype bean,以便每个订单都由 Order 类的单独实例处理。

混合范围:注意事项

我从惨痛的教训中学到的一件事是,混合使用 Singleton 和 Prototype beans 可能会导致意想不到的问题。例如,将 Prototype 范围的 bean 注入到 Singleton bean 中可能会导致 Singleton bean 始终使用 Prototype bean 的同一实例。为了避免这种情况,我通常注入一个 Provider 或使用 @Lookup 注释来确保每次需要时都会创建 Prototype bean 的新实例。

@Service
public class SingletonService {

    @Autowired
    private Provider myPrototypeServiceProvider;

    public void usePrototypeService() {
        MyPrototypeService prototypeService = myPrototypeServiceProvider.get();
        prototypeService.execute();
    }
}

在此示例中,myPrototypeServiceProvider.get() 确保每次在 Singleton bean 中调用时都会创建 MyPrototypeService 的新实例。

再见 !

理解 Spring 中的 Singleton 和 Prototype bean 范围的细微差别对于我作为开发人员的旅程至关重要。根据用例,这两种示波器都具有明显的优势,选择正确的示波器可以显着影响应用程序的性能和设计。

根据我的经验,Singleton 由于其效率和简单性而成为大多数 bean 的首选范围,而 Prototype 则保留给那些每次都需要新实例的特殊情况。通过仔细考虑 bean 的有状态性以及它们在应用程序中的使用方式,我可以做出明智的决策,从而构建更好、更易于维护的 Spring 应用程序。

版本聲明 本文轉載於:https://dev.to/isaactony/singleton-and-prototype-spring-bean-scopes-a-detailed-exploration-1gpl?1如有侵犯,請聯絡[email protected]刪除
最新教學 更多>
  • 為什麼Go的main函數有死迴圈?
    為什麼Go的main函數有死迴圈?
    Go 運行時:主函數中無限循環之謎Go 運行時的核心位於src/runtime/proc.go,其中有一個令人費解的功能:主函數末尾有一個無限的for 迴圈。人們可能想知道為什麼運行時中存在這樣一個看似毫無意義的構造。 目的:偵測致命錯誤深入研究程式碼,很明顯循環服務於錯誤處理的關鍵目的。當發生致命...
    程式設計 發佈於2024-11-07
  • iostream 與 iostream.h:現代 C++ 應該使用哪一個?
    iostream 與 iostream.h:現代 C++ 應該使用哪一個?
    iostream 和iostream.h 之間的區別在C 中,程式設計師可能會遇到兩個具有類似目的的術語:iostream 和iostream.h 。本指南旨在闡明兩者之間的根本差異。 iostream.h:已棄用的舊版iostream.h 是 C 函式庫中的一個頭文件,它提供一組輸入/輸出函數。對...
    程式設計 發佈於2024-11-07
  • VLONE Clothing:重新定義都市時尚的街頭服飾品牌
    VLONE Clothing:重新定義都市時尚的街頭服飾品牌
    VLONE 是少数几个在快速变化的市场中取得超越街头服饰行业所能想象的成就的品牌之一。 VLONE 由 A$AP Mob 集体的电影制片人之一 A$AP Bari 创立,现已发展成为一个小众项目,有时甚至成为都市时尚界的国际知名品牌。 VLONE 凭借大胆的图案、深厚的文化联系和限量版发售,在时尚界...
    程式設計 發佈於2024-11-07
  • 如何使用PDO查詢單行中的單列?
    如何使用PDO查詢單行中的單列?
    使用 PDO 查詢單行中的單列處理針對單行中特定列的 SQL 查詢時,通常需要檢索直接取值,無需循環。要使用 PDO 完成此操作,fetchColumn() 方法就派上用場了。 fetchColumn() 的語法為:$col_value = $stmt->fetchColumn([column...
    程式設計 發佈於2024-11-07
  • 我如何建立 PeerSplit:一個免費的點對點費用分攤應用程式 — 從構思到發布僅需數週時間
    我如何建立 PeerSplit:一個免費的點對點費用分攤應用程式 — 從構思到發布僅需數週時間
    我构建了 PeerSplit——一个免费的、点对点的 Splitwise 替代品——从想法到发布仅用了两周时间! PeerSplit 是一款本地优先的应用程序,用于分配团体费用。它可以离线工作,100% 免费且私密,不需要注册或任何个人数据。 以下是我如何构建它以及我在此过程中学到的一切。 ...
    程式設計 發佈於2024-11-07
  • 如何在 PHP 中解析子網域的根網域?
    如何在 PHP 中解析子網域的根網域?
    在 PHP 中從子域解析網域名稱在 PHP 中,從子域中提取根網域是一項常見任務。當您需要識別與子網域關聯的主網站時,這非常有用。為了實現這一目標,讓我們探索一個解決方案。 提供的程式碼片段利用 parse_url 函數將 URL 分解為其元件,包括網域名稱。隨後,它使用正規表示式來隔離根域,而忽略...
    程式設計 發佈於2024-11-07
  • 使用 Socket.io 建立即時應用程式
    使用 Socket.io 建立即時應用程式
    介紹 Socket.io 是一個 JavaScript 函式庫,可讓 Web 用戶端和伺服器之間進行即時通訊。它支援創建互動式動態應用程序,例如聊天室、多人遊戲和直播。憑藉其易於使用的 API 和跨平台相容性,Socket.io 已成為建立即時應用程式的熱門選擇。在本文中,我們將探...
    程式設計 發佈於2024-11-07
  • 重寫 `hashCode()` 和 `equals()` 如何影響 HashMap 效能?
    重寫 `hashCode()` 和 `equals()` 如何影響 HashMap 效能?
    了解equals 和hashCode 在HashMap 中的工作原理Java 中的HashMap 使用hashCode() 和equals() 方法的組合來有效地儲存和檢索鍵值對。當新增新的鍵值對時,首先計算鍵的hashCode()方法,以確定該條目將放置在哪個雜湊桶中。然後使用 equals() ...
    程式設計 發佈於2024-11-07
  • 使用 Google Apps 腳本和 Leaflet.js 建立互動式 XY 圖像圖
    使用 Google Apps 腳本和 Leaflet.js 建立互動式 XY 圖像圖
    Google Maps has a ton of features for plotting points on a map, but what if you want to plot points on an image? These XY Image Plot maps are commonly...
    程式設計 發佈於2024-11-07
  • 理解 React 中的狀態變數:原因和方法
    理解 React 中的狀態變數:原因和方法
    在深入研究狀態變數之前,讓我們先來分析一下 React 元件的工作原理吧! 什麼是 React 元件? 在 React 中,元件是一段可重複使用的程式碼,代表使用者介面 (UI) 的一部分。它可以像 HTML 按鈕一樣簡單,也可以像完整的頁面一樣複雜。 React...
    程式設計 發佈於2024-11-07
  • Miva 的日子:第 4 天
    Miva 的日子:第 4 天
    這是 100 天 Miva 編碼挑戰的第四天。我跳過了第三天的報告,因為我被困在我的網頁設計專案中,需要改變節奏。這就是為什麼我今天決定深入研究 JavaScript。 JavaScript JavaScript 就像是系統和網站的行為元件。它為網站增加了互動性和回應能力,使其成為網頁設計和開發...
    程式設計 發佈於2024-11-07
  • TailGrids React:+ Tailwind CSS React UI 元件
    TailGrids React:+ Tailwind CSS React UI 元件
    我們很高興推出 TailGrids React,這是您的新首選工具包,可用於輕鬆建立令人驚嘆的響應式 Web 介面。 TailGrids React 提供了超過 600 免費和高級 React UI 元件、區塊、部分和模板的大量集合 - 所有這些都是用 Tailwind CSS 精心製作的。 無論...
    程式設計 發佈於2024-11-07
  • 如何用列表值反轉字典?
    如何用列表值反轉字典?
    使用列表值反轉字典:解決方案在本文中,我們探討了使用列表值反轉字典的挑戰。給定一個索引字典,其中鍵是檔案名,值是這些檔案中出現的單字列表,我們的目標是建立一個倒排字典,其中單字是鍵,值是檔案名稱列表。 提供的反轉函數 invert_dict,不適用於以列表值作為鍵的字典,因為它會失敗並顯示“Type...
    程式設計 發佈於2024-11-07
  • 現代 Web 開發框架:比較流行的框架及其用例
    現代 Web 開發框架:比較流行的框架及其用例
    在快速發展的 Web 開發領域,選擇正確的框架可以顯著影響專案的成功。本文深入研究了一些最受歡迎的 Web 開發框架,比較了它們的優勢和理想用例,以幫助開發人員做出明智的決策。 反應 概述 React 由 Facebook 開發和維護,是一個用於建立使用者介面的 J...
    程式設計 發佈於2024-11-07
  • 如何在 Go 1.18 中安全地使用泛型類型解組 JSON?
    如何在 Go 1.18 中安全地使用泛型類型解組 JSON?
    Unmarshal 中的泛型使用(Go 1.18)在Go 1.18 中使用泛型時,例如創建一個容器來保存各種報告類型,可能會出現類型限制。考慮以下設定:由結構表示的多種報告類型具有通用類型參數的ReportContainer 包裝器可報告,約束為實作可報告介面鑑別器ReportType 在解組過程中...
    程式設計 發佈於2024-11-07

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3