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

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

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

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]刪除
最新教學 更多>
  • Java數組中元素位置查找技巧
    Java數組中元素位置查找技巧
    在Java數組中檢索元素的位置 利用Java的反射API將數組轉換為列表中,允許您使用indexof方法。 (primitives)(鏈接到Mishax的解決方案) 用於排序陣列的數組此方法此方法返回元素的索引,如果發現了元素的索引,或一個負值,指示應放置元素的插入點。
    程式設計 發佈於2025-05-17
  • 如何為PostgreSQL中的每個唯一標識符有效地檢索最後一行?
    如何為PostgreSQL中的每個唯一標識符有效地檢索最後一行?
    postgresql:為每個唯一標識符在postgresql中提取最後一行,您可能需要遇到與數據集合中每個不同標識的信息相關的信息。考慮以下數據:[ 1 2014-02-01 kjkj 在數據集中的每個唯一ID中檢索最後一行的信息,您可以在操作員上使用Postgres的有效效率: id dat...
    程式設計 發佈於2025-05-17
  • 查找當前執行JavaScript的腳本元素方法
    查找當前執行JavaScript的腳本元素方法
    如何引用當前執行腳本的腳本元素在某些方案中理解問題在某些方案中,開發人員可能需要將其他腳本動態加載其他腳本。但是,如果Head Element尚未完全渲染,則使用document.getElementsbytagname('head')[0] .appendChild(v)的常規方...
    程式設計 發佈於2025-05-17
  • 大批
    大批
    [2 數組是對象,因此它們在JS中也具有方法。 切片(開始):在新數組中提取部分數組,而無需突變原始數組。 令ARR = ['a','b','c','d','e']; // USECASE:提取直到索引作...
    程式設計 發佈於2025-05-17
  • 您可以使用CSS在Chrome和Firefox中染色控制台輸出嗎?
    您可以使用CSS在Chrome和Firefox中染色控制台輸出嗎?
    在javascript console 中顯示顏色是可以使用chrome的控制台顯示彩色文本,例如紅色的redors,for for for for錯誤消息? 回答是的,可以使用CSS將顏色添加到Chrome和Firefox中的控制台顯示的消息(版本31或更高版本)中。要實現這一目標,請使用以下...
    程式設計 發佈於2025-05-17
  • 將圖片浮動到底部右側並環繞文字的技巧
    將圖片浮動到底部右側並環繞文字的技巧
    在Web設計中圍繞在Web設計中,有時可以將圖像浮動到頁面右下角,從而使文本圍繞它纏繞。這可以在有效地展示圖像的同時創建一個吸引人的視覺效果。 css位置在右下角,使用css float and clear properties: img { 浮點:對; ...
    程式設計 發佈於2025-05-17
  • 如何簡化PHP中的JSON解析以獲取多維陣列?
    如何簡化PHP中的JSON解析以獲取多維陣列?
    php 試圖在PHP中解析JSON數據的JSON可能具有挑戰性,尤其是在處理多維數組時。 To simplify the process, it's recommended to parse the JSON as an array rather than an object.To do...
    程式設計 發佈於2025-05-17
  • `console.log`顯示修改後對象值異常的原因
    `console.log`顯示修改後對象值異常的原因
    foo = [{id:1},{id:2},{id:3},{id:4},{id:id:5},],]; console.log('foo1',foo,foo.length); foo.splice(2,1); console.log('foo2', foo, foo....
    程式設計 發佈於2025-05-17
  • Python高效去除文本中HTML標籤方法
    Python高效去除文本中HTML標籤方法
    在Python中剝離HTML標籤,以獲取原始的文本表示 僅通過Python的MlStripper 來簡化剝離過程,Python Standard庫提供了一個專門的功能,MLSTREPERE,MLSTREPERIPLE,MLSTREPERE,MLSTREPERIPE,MLSTREPERCE,MLST...
    程式設計 發佈於2025-05-17
  • Go語言如何動態發現導出包類型?
    Go語言如何動態發現導出包類型?
    與反射軟件包中的有限類型的發現能力相反,本文探索了替代方法,探索了在Runruntime。 go import( “ FMT” “去/進口商” ) func main(){ pkg,err:= incorter.default()。導入(“ time”) 如果er...
    程式設計 發佈於2025-05-17
  • 如何從Google API中檢索最新的jQuery庫?
    如何從Google API中檢索最新的jQuery庫?
    從Google APIS 問題中提供的jQuery URL是版本1.2.6。對於檢索最新版本,以前有一種使用特定版本編號的替代方法,它是使用以下語法:獲取最新版本:未壓縮)While these legacy URLs still remain in use, it is recommended ...
    程式設計 發佈於2025-05-17
  • 如何將多種用戶類型(學生,老師和管理員)重定向到Firebase應用中的各自活動?
    如何將多種用戶類型(學生,老師和管理員)重定向到Firebase應用中的各自活動?
    Red: How to Redirect Multiple User Types to Respective ActivitiesUnderstanding the ProblemIn a Firebase-based voting app with three distinct user type...
    程式設計 發佈於2025-05-17
  • Java中如何使用觀察者模式實現自定義事件?
    Java中如何使用觀察者模式實現自定義事件?
    在Java 中創建自定義事件的自定義事件在許多編程場景中都是無關緊要的,使組件能夠基於特定的觸發器相互通信。本文旨在解決以下內容:問題語句我們如何在Java中實現自定義事件以促進基於特定事件的對象之間的交互,定義了管理訂閱者的類界面。 以下代碼片段演示瞭如何使用觀察者模式創建自定義事件: args...
    程式設計 發佈於2025-05-17
  • 可以在純CS中將多個粘性元素彼此堆疊在一起嗎?
    可以在純CS中將多個粘性元素彼此堆疊在一起嗎?
    [2这里: https://webthemez.com/demo/sticky-multi-header-scroll/index.html </main> <section> { display:grid; grid-template-...
    程式設計 發佈於2025-05-17
  • 如何在Java的全屏獨家模式下處理用戶輸入?
    如何在Java的全屏獨家模式下處理用戶輸入?
    Handling User Input in Full Screen Exclusive Mode in JavaIntroductionWhen running a Java application in full screen exclusive mode, the usual event ha...
    程式設計 發佈於2025-05-17

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

Copyright© 2022 湘ICP备2022001581号-3