Spring系列8:bean的作用域

article/2025/9/22 21:59:01

本文内容

  1. bean定义信息的意义
  2. 介绍6种bean的作用域

bean定义信息的意义

Spring中区分下类、类定义信息,类实例对象的概念?不容易理解,以餐馆中点炒饭为例。

类: 相当于你看到菜单上炒饭这个菜品,有这个菜。

类定义信息:相当于炒饭的烹饪法,烹饪法只有一份

类实例对象: 相当于按照上面烹饪法炒出来的一份炒饭,可以炒分多份出来。

Spring容器中创建了一个类定义信息的,就可以根据这个定义信息来创建个类实例对象出来,这个理解了很关键。Spring中不仅可以控制 bean 对象中的各种依赖项和配置值,还可以控制 bean 额作用范围。

介绍6种bean的作用域

Spring Framework 支持6个bean的作用域,其中4个仅在web类型的 ApplicationContext 中可用。详细见下表

作用域描述
singleton(默认)将单个 bean 定义限定为每个 Spring IoC 容器的单个对象实例。
prototype将单个 bean 定义限定为任意数量的对象实例
request将单个 bean 定义限定为单个 HTTP 请求的生命周期。也就是说,每个 HTTP 请求都有自己的 bean 实例,该实例是在单个 bean 定义的后面创建的。仅在web类型的 ApplicationContext有效。
session将单个 bean 定义限定为 HTTP 会话的生命周期。仅在web类型的 ApplicationContext有效。
application将单个 bean 定义限定为 ServletContext 的生命周期。仅在web类型的 ApplicationContext有效。
websocket将单个 bean 定义限定为 WebSocket 的生命周期。仅在web类型的 ApplicationContext有效。

从 Spring 3.0 开始,线程范围可用,但默认情况下未注册。SimpleThreadScope感兴趣可以详细看下面自定义作用域。

singleton

只有一个单例 bean 的共享实例被管理,并且所有对具有与该 bean 定义匹配的一个或多个 ID 的 bean 的请求都会导致 Spring 容器返回一个特定的 bean 实例。"蝎子粑粑独一份"。注意是一个IoC容器内。

singleton

prototype

原型作用域下每次容器都会创建一个新的 bean 实例。通常来说,对有状态 bean适合使用原型,对无状态 bean适合使用单例。

prototype

下面的配置节指定了bean的作用域是原型的。

<bean id="accountService" class="x.y.z.AccountService" scope="prototype"/>

与其他范围相比,Spring 不管理原型 bean 的完整生命周期。容器实例化、配置和以其他方式组装原型对象并将其传递给客户端,由客户端去管理。bean生命周期后面介绍。

request, session, application, webSocket

这4个在web的应用上下文中使用的作用域,暂不展开讲,留给后面写spring mvc 专门讲。

自定义作用域和使用

如何自定义?

可以通过实现org.springframework.beans.factory.config.Scope自定义作用域。Scope 接口有四种方法可以从作用域中获取对象,将它们从作用域中移除,并让它们被销毁。

package org.springframework.beans.factory.config;
public interface Scope {// 从底层范围返回具有给定名称的对象Object get(String name, ObjectFactory<?> objectFactory);// 从底层范围中删除具有给定的对象Object remove(String name);// 注册要在作用域中指定对象的销毁时执行的回调void registerDestructionCallback(String name, Runnable callback);// 省略
}

打铁要趁热,直接上SimpleThreadScope的源码,解析下线程级别作用域是如何实现的。

package org.springframework.context.support;public class SimpleThreadScope implements Scope {private static final Log logger = LogFactory.getLog(SimpleThreadScope.class);// 1 bean是存放在ThreadLocal中的 绑定了当前线程 private final ThreadLocal<Map<String, Object>> threadScope =new NamedThreadLocal<Map<String, Object>>("SimpleThreadScope") {@Overrideprotected Map<String, Object> initialValue() {return new HashMap<>();}};// 2 查ThreadLocal,有对应bean就直接返回,没有就创建一个放入ThreadLocal,在返回@Overridepublic Object get(String name, ObjectFactory<?> objectFactory) {Map<String, Object> scope = this.threadScope.get();Object scopedObject = scope.get(name);if (scopedObject == null) {scopedObject = objectFactory.getObject();scope.put(name, scopedObject);}return scopedObject;}// 3 从ThreadLocal中移除bean@Override@Nullablepublic Object remove(String name) {Map<String, Object> scope = this.threadScope.get();return scope.remove(name);}// 4 销毁回调@Overridepublic void registerDestructionCallback(String name, Runnable callback) {logger.warn("SimpleThreadScope does not support destruction callbacks. " +"Consider using RequestScope in a web environment.");}@Override@Nullablepublic Object resolveContextualObject(String key) {return null;}@Overridepublic String getConversationId() {return Thread.currentThread().getName();}}

如何使用?

  1. 先将自定义的scope注入到容器中

    编码的方式注册: ConfigurableBeanFactory接口提供了registerScope来注册自定义的scope。

    Scope threadScope = new SimpleThreadScope();
    beanFactory.registerScope("thread", threadScope);

    配置文件方式的注册: 使用 CustomScopeConfigurer 以声明方式进行注册

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttps://www.springframework.org/schema/aop/spring-aop.xsd"><bean class="org.springframework.beans.factory.config.CustomScopeConfigurer"><property name="scopes"><map><entry key="thread"><bean class="org.springframework.context.support.SimpleThreadScope"/></entry></map></property></bean>
    </beans>    
  1. bean配置中使用

    使用方式普通的scope一样。

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttps://www.springframework.org/schema/aop/spring-aop.xsd"><bean class="org.springframework.beans.factory.config.CustomScopeConfigurer"><property name="scopes"><map><entry key="thread"><bean class="org.springframework.context.support.SimpleThreadScope"/></entry></map></property></bean><bean id="thing2" class="x.y.Thing2" scope="thread"><property name="name" value="Rick"/><aop:scoped-proxy/></bean><bean id="thing1" class="x.y.Thing1"><property name="thing2" ref="thing2"/></bean></beans>

总结

本文Spring中的7种作用域,以及如何自定义作用域并使用。下一篇介绍基于注解的Spring容器配置。

知识分享,转载请注明出处。学无先后,达者为先!


http://chatgpt.dhexx.cn/article/x3loNaUg.shtml

相关文章

【Java第34期】:Bean的六种作用域

作者&#xff1a;有只小猪飞走啦 博客地址&#xff1a;https://blog.csdn.net/m0_62262008?typeblog 内容&#xff1a;介绍Bean的六种作用域的效果以及适用场景 文章目录 前言一&#xff0c;作用域定义以及Bean的六种作用域是什么&#xff1f;二&#xff0c;singleton&#…

Bean的六种作用域

什么是Bean的作用域呢? 这里的"作用域"还和Java中的类级,方法级等这几个作用域概念不太一样,我自己的一个理解是:在Spring执行的这段时间中,Bean的作用域就只有单例和多例这两种,在执行respect这段时间之中,就有它自己的作用域,而到了session中又有它自己的作用域,…

Spring Bean的作用域

在Spring中&#xff0c;bean作用域用于确定哪种类型的bean实例应该从Spring容器中返回给调用者。 目前Spring Bean的作用域或者说范围主要有五种。 作用域描述singleton在spring IoC容器仅存在一个Bean实例&#xff0c;Bean以单例方式存在&#xff0c;bean作用域范围的默认值…

设计原则-依赖倒置

名称&#xff1a;依赖倒置原则&#xff08;Dependence Inversion Principle&#xff09; 定义&#xff1a;程序要依赖于抽象接口&#xff0c;不要依赖于具体实现。依赖倒置原则的中心思想是面向接口编程。 高层模块不应依赖于低层模块&#xff0c;二者都应该依赖于抽象抽象不…

C++之依赖倒置原则

C之依赖倒置原则 1. 依赖于具体抽象&#xff08;接口&#xff09;&#xff0c;不依赖于具体的实现&#xff0c;也就是针对接口编程。 2. 实现高层业务和实现层、实现层和实现层之间的解耦合&#xff1b; 实例&#xff1a; 电脑框架和电脑内部的配件产品&#xff08;或提供配…

【软件架构设计原则】开闭原则和依赖倒置原则

文章目录 软件架构设计原则开闭原则依赖倒置原则最后 软件架构设计原则 本文通过实例来讲解 开闭原则依赖导致原则 开闭原则 开闭原则&#xff08;Open-Close Principle&#xff0c;OCP&#xff09;是指一个软件实体&#xff08;如类、模块和函数&#xff09;应该对扩展开放…

java 依赖倒置_Java设计原则—依赖倒置原则(转)

依赖倒置原则(Dependence Inversion Principle&#xff0c;DIP)的原始定义&#xff1a; 高层模块不应该依赖底层模块&#xff0c;两者都应该依赖其抽象&#xff1b; 抽象不应该依赖细节&#xff1b; 细节应该依赖抽象。 依赖倒置原则在Java语言中的表现是&#xff1a; 模块间的…

设计模式 依赖倒置原则

文章目录 依赖倒置原则依赖倒置原则实战使用依赖倒置原则进行改变案例中两种方式的类图 依赖倒置原则 定义: 程序要依赖于抽象接口, 不要依赖于具体实现, 对抽象进行编程, 而不是对实现进行编程, 降低了客户与实现模块的耦合. 高层模块不应该依赖底层模块, 都应该依赖抽象(接口…

依赖倒置原则应用-司机开车案例

依赖倒置原则 依赖倒置原则(Dependence Inversion Principle)是程序要依赖于抽象接口&#xff0c;不要依赖于具体实现。简单的说就是要求对抽象进行编程&#xff0c;不要对实现进行编程&#xff0c;这样就降低了客户与实现模块间的耦合。 依赖倒置原则三层含义&#xff1a; …

4.3 依赖倒置原则

一. 依赖倒置原则的定义 1.核心思想 依赖倒置原则&#xff08;Dependence Inversion Principle&#xff0c;DIP&#xff09; *1.高层模块 不应该依赖 低层模块, 二者都应该依赖其抽象; *2.抽象 不应该依赖 细节, 细节 应该依赖 抽象; 接口和抽象类价值在于设计; *3.依赖倒…

C# 依赖倒置原则(DIP)

目录 一&#xff0c;引子 1.1 传统的程序架构 1.2 依赖倒置 1.3 依赖倒置的作用 二&#xff0c;依赖注入 一&#xff0c;引子 1.1 传统的程序架构 在程序执行过程中&#xff0c;传统的程序架构如图&#xff1a; 可以看到&#xff0c;在传统的三层架构中&#xff0c;层与…

设计模式-依赖倒置原则

依赖倒置原则 1 依赖倒置原则的定义 依赖倒置原则&#xff08;Dependence Inversion Principle,DIP&#xff09;这个名字看着有点别扭&#xff0c;“依赖”还“倒置”&#xff0c;这到底是什么意思&#xff1f;依赖倒置原则的原始定义是&#xff1a; High level modules shou…

C++ 依赖倒置原则

.依赖倒置原则 定义 高层模块不应该依赖于底层模块&#xff0c;而应该依赖于抽象。抽象不应依赖于细节&#xff0c;细节应依赖于抽象。解决的问题 类A直接依赖类B&#xff0c;假如要将类A改为依赖类C&#xff0c;则必须通过修改类A的代码来达成。这种场景下&#xff0c;类A一般…

【设计原则】依赖倒置原则 (面向接口编程)

本文将以Java为基础&#xff0c;讲解开发中&#xff0c;面向接口编程的知识&#xff0c;只要以简单的例子为主&#xff0c;讲解如何进行面向接口编程,并会区分其于面向实现编程的区别。下面先讲一讲依赖倒置原则&#xff0c;再过渡到案例解释。 本文目的在于用极其简单的图解帮…

设计模式 — 6大设计原则(依赖倒置和接口隔离原则)

设计模式 依赖倒置原则示例 一示例 二依赖的三种写法总结 接口隔离原则实例 一总结 依赖倒置原则 依赖倒置原则&#xff08;Dependence Inversion Principle&#xff0c;DIP&#xff09;这个名字看着有点别扭&#xff0c;“依赖” 还 “倒置” &#xff0c;这到底是什么意思&a…

【六大设计原则-SOLID】

SOLID简介&#xff1a; 历史&#xff1a;由Robert CMartin汇总并推广 目标&#xff1a; 使软件更容易被改动是软件更容易被理解构建可以在多个软件系统中复用的组件 组成&#xff1a; 名称简写含义单一职责原则 SRP Single Responsibility Principle 初始定义&#xff08…

SOLID原则:解释和实例

在面向对象编程中,SOLID是5个重要的设计原则的缩写。首先是由著名的软件大师Robert C.Martin (Bob 大叔)在Design Principles and Design Patterns 中提出, 后来Michael Feathers 用SOLID来概括这五大原则。 SOLID原则使得软件设计更加容易理解、灵活和可维护。作为一名软件…

SOLID原则的含义和具体使用

单一职责原则&#xff08;SRP&#xff09;开放封闭原则&#xff08;OCP&#xff09;里氏替换原则&#xff08;LSP&#xff09;接口隔离原则&#xff08;ISP&#xff09;依赖倒置原则&#xff08;DIP&#xff09;小结 SOLID 是面向对象设计5大重要原则的首字母缩写&#xff0c;当…

设计模式:SOLID原则

单一职责原则 Single Responsibility Principle&#xff08;SRP&#xff09; 接口职责应该单一&#xff0c;不要承担过多的职责。 开放封闭原则 Open Closed Principle&#xff08;OCP&#xff09; 添加一个新的功能应该是&#xff0c;在已有代码基础上扩展代码&#xff08;…

设计模式之SOLID原则

介绍 设计模式中的SOLID原则&#xff0c;分别是单一原则、开闭原则、里氏替换原则、接口隔离原则、依赖倒置原则。前辈们总结出来的&#xff0c;遵循五大原则可以使程序解决紧耦合&#xff0c;更加健壮。 SRP 单一责任原则 OCP …