当我第一次开始使用 Spring 时,最让我感兴趣的概念之一是 bean 范围的想法。 Spring 提供了各种 bean 作用域,用于确定在 Spring 容器内创建的 bean 的生命周期。最常用的两个范围是 Singleton 和 Prototype。了解这些范围对于设计高效且有效的 Spring 应用程序至关重要,所以让我带您了解我对它们的了解。
在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——那些不保存任何客户端特定信息的 Bean。示例包括:
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。一些典型的用例包括:
使用 Prototype beans 的主要优点是它在创建新实例时提供的灵活性。这在处理有状态对象时特别有用。然而,在性能和资源使用方面需要权衡。由于每次都会创建一个新实例,因此可能会导致更高的内存消耗和更频繁的垃圾收集。此外,与 Singleton bean 不同,Spring 不管理 Prototype bean 除了创建之外的生命周期,因此我必须手动处理这些 bean 的销毁和清理。
设计 Spring 应用程序时我面临的关键决策之一是在 Singleton 和 Prototype 范围之间进行选择。以下是我考虑的因素的总结:
让我提供一个实际场景,可能有助于阐明何时使用每个范围。假设我正在构建一个在线购物应用程序。
我从惨痛的教训中学到的一件事是,混合使用 Singleton 和 Prototype beans 可能会导致意想不到的问题。例如,将 Prototype 范围的 bean 注入到 Singleton bean 中可能会导致 Singleton bean 始终使用 Prototype bean 的同一实例。为了避免这种情况,我通常注入一个 Provider 或使用 @Lookup 注释来确保每次需要时都会创建 Prototype bean 的新实例。
@Service public class SingletonService { @Autowired private ProvidermyPrototypeServiceProvider; public void usePrototypeService() { MyPrototypeService prototypeService = myPrototypeServiceProvider.get(); prototypeService.execute(); } }
在此示例中,myPrototypeServiceProvider.get() 确保每次在 Singleton bean 中调用时都会创建 MyPrototypeService 的新实例。
理解 Spring 中的 Singleton 和 Prototype bean 范围的细微差别对于我作为开发人员的旅程至关重要。根据用例,这两种示波器都具有明显的优势,选择正确的示波器可以显着影响应用程序的性能和设计。
根据我的经验,Singleton 由于其效率和简单性而成为大多数 bean 的首选范围,而 Prototype 则保留给那些每次都需要新实例的特殊情况。通过仔细考虑 bean 的有状态性以及它们在应用程序中的使用方式,我可以做出明智的决策,从而构建更好、更易于维护的 Spring 应用程序。
免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。
Copyright© 2022 湘ICP备2022001581号-3