Spring 中的 Bean 作用域

简介

所谓作用域,其实就是说这个东西哪个范围内可以被使用。如我们定义类的成员变量的时候使用的publicprivate等这些也是作用域的概念。

Spring的Bean的作用域,描述的就是这个Bean在哪个范围内可以被使用。不同的作用域决定了 Bean 的创建、管理和销毁的方式。

常见的作用域有Singleton、Prototype、Request、Session、Application这五种。我们在代码中,可以在定义一个Bean的时候,通过@Scope 注解来指定他的作用域

@Service
@Scope("prototype")
public class HollisTestService{
    
}

这五种作用域的解释如下:

  1. 单例(Singleton)
    • 默认作用域。
    • 对于每个 Spring IoC 容器,只创建一个 Bean 实例。
    • 适用于全局共享的状态。
  • 原型(Prototype)
    • 每次请求都会创建一个新的 Bean 实例。
    • 适用于所有状态都是非共享的情况。
  1. 请求(Request)
    • 仅在 Web 应用程序中有效。
    • 每个 HTTP 请求都会创建一个新的 Bean 实例。
    • 用于请求级别的数据存储和处理。
  1. 会话(Session)
    • 仅在 Web 应用程序中有效。
    • 每个 HTTP 会话都会创建一个新的 Bean 实例。
    • 适用于会话级别的数据存储和处理。
  1. 应用(Application)
    • 仅在 Web 应用程序中有效。
    • 在 ServletContext 的生命周期内,只创建一个 Bean 实例。
    • 适用于全应用程序级别的共享数据。
  1. Websocket
    • 仅在 Web 应用程序中有效。
    • 在 Websocket 的生命周期内,只创建一个 Bean 实例。
    • 适用于websocket级别的共享数据。

一般来说我们都是使用Singleton的作用域,有的时候也会用Prototype,其他几个用得不多。

以下两张图是Spring官方给的关于singleton和prototype的区别。其实就是会创建一个Bean还是多个Bean的区别:

作用域与循环依赖

Spring在解决循环依赖时,只解决了单例作用域的,别的作用域没有解决。

自定义作用域

除了Spring官方提供的这些作用域以外,我们还可以自定义我们自己的作用域,Spring提供了这方面的支持。

要自定义一个 Spring 的作用域,需要实现 org.springframework.beans.factory.config.Scope 接口。这个接口要求实现几个关键方法来管理 Bean 的生命周期。

public interface Scope {

	Object get(String name, ObjectFactory<?> objectFactory);

	@Nullable
	Object remove(String name);

	void registerDestructionCallback(String name, Runnable callback);

	@Nullable
	Object resolveContextualObject(String key);


	@Nullable
	String getConversationId();
}

接下来,我们需要实现接口的方法,例如 get(创建或检索 Bean 实例)、remove(销毁 Bean 实例)等。

import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.config.Scope;

public class MyCustomScope implements Scope {

    @Override
    public Object get(String name, ObjectFactory<?> objectFactory) {
        // 实现获取 Bean 的逻辑
        return objectFactory.getObject();
    }

    @Override
    public Object remove(String name) {
        // 实现移除 Bean 的逻辑
        return null;
    }

    @Override
    public void registerDestructionCallback(String name, Runnable callback) {
        // 注册 Bean 销毁时的回调
    }

    @Override
    public Object resolveContextualObject(String key) {
        // 用于解析相关上下文数据
        return null;
    }

    @Override
    public String getConversationId() {
        // 返回当前会话的 ID
        return null;
    }
}

接下来,我们需要 Spring 配置中注册这个自定义的作用域。这可以通过 ConfigurableBeanFactory.registerScope 方法实现。


import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AppConfig {

    @Bean
    public MyCustomScope myCustomScope(ConfigurableBeanFactory beanFactory) {
        MyCustomScope scope = new MyCustomScope();
        beanFactory.registerScope("myCustomScope", scope);
        return scope;
    }
}

在 Bean 定义中使用自定义的作用域的名称。Spring 容器将会根据你的自定义逻辑来创建和管理这些 Bean。

@Component
@Scope("myCustomScope")
public class MyScopedBean {
    // ...
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

埃泽漫笔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值