it编程 > 编程语言 > Java

Spring 中完整的 Scope 选项实例详解

2人参与 2026-09-21 Java

spring 的 scope 属性确实不止 singletonprototype 两个。根据应用类型和 spring 生态的不同,一共有 8 种可选值。它们可以分为三类:核心作用域、web 作用域、扩展作用域。

一、核心作用域(2 个)

这两个是 spring 容器内置的基础作用域,适用于所有类型的应用。

作用域说明
singleton默认值,容器中只有一个实例,全局共享
prototype每次获取都创建新实例
@component
@scope("singleton")  // 默认,可省略
public class userservice { }
@component
@scope("prototype")
public class shoppingcart { }

二、web 作用域(4 个)

这 4 个作用域只在 web 应用中有效,需要 webapplicationcontext 支持。

1. request

每个 http 请求创建一个实例,请求结束后销毁。

@component
@scope(value = "request", proxymode = scopedproxymode.target_class)
public class requestcontext {
    private string requestid;
    // ...
}

2. session

每个 http session 创建一个实例,session 失效时销毁。

@component
@scope(value = "session", proxymode = scopedproxymode.target_class)
public class usersession {
    private user currentuser;
    // ...
}

3. application

每个 servletcontext 创建一个实例,整个 web 应用共享。

@component
@scope(value = "application", proxymode = scopedproxymode.target_class)
public class appcounter {
    private atomicinteger totalvisits = new atomicinteger(0);
    // ...
}

4. websocket

每个 websocket 会话创建一个实例,连接关闭时销毁。spring 5+ 支持。

@component
@scope(value = "websocket", proxymode = scopedproxymode.target_class)
public class websocketsessionbean {
    private string sessionid;
    // ...
}

三、扩展作用域(2 个)

这两个不在 spring framework 核心中,而是来自 spring cloud 或自定义实现。

5. refresh(spring cloud)

用于 spring cloud 的配置动态刷新。当配置中心(如 nacos、config server)的配置变更时,被 @refreshscope 标注的 bean 会被重新创建,注入最新的配置值。

@component
@refreshscope  // 等价于 @scope("refresh")
public class configurablebean {
    @value("${app.timeout}")
    private int timeout;
}

当调用 /actuator/refresh 端点时,refresh 作用域的 bean 会被销毁并重新创建,timeout 会更新为最新值。

6. globalsession(旧版 portlet)

用于 portlet 应用的全局会话作用域。在 portlet 规范中,globalsession 表示跨所有 portlet 的全局会话。spring mvc 应用不使用这个作用域,它在 spring 5 之后已经很少见。

<bean id="globalsessionbean" class="com.example.mybean" scope="globalsession"/>

四、自定义作用域

除了以上 6 个内置作用域,spring 还允许通过实现 scope 接口定义自定义作用域。常见的自定义作用域有:

7. thread(线程作用域)

每个线程一个实例,常用于线程隔离的场景。

public class threadscope implements scope {
    private final threadlocal<map<string, object>> threadscope = 
        threadlocal.withinitial(hashmap::new);
    @override
    public object get(string name, objectfactory<?> objectfactory) {
        return threadscope.get().computeifabsent(name, k -> objectfactory.getobject());
    }
    @override
    public object remove(string name) {
        return threadscope.get().remove(name);
    }
    @override
    public void registerdestructioncallback(string name, runnable callback) {
    }
    @override
    public object resolvecontextualobject(string key) {
        return null;
    }
    @override
    public string getconversationid() {
        return thread.currentthread().getname();
    }
}

注册:

@configuration
public class scopeconfig {
    @bean
    public customscopeconfigurer customscopeconfigurer() {
        customscopeconfigurer configurer = new customscopeconfigurer();
        configurer.addscope("thread", new threadscope());
        return configurer;
    }
}

使用:

@component
@scope("thread")
public class threadscopedbean {
}

8. 其他自定义作用域

根据业务需要,还可以定义更多作用域,例如:

五、8 个 scope 汇总表

序号作用域来源实例范围适用场景
1singletonspring 核心整个容器一个无状态服务
2prototypespring 核心每次获取新实例有状态对象
3requestspring web每个 http 请求一个请求级数据
4sessionspring web每个 session 一个用户会话数据
5applicationspring web每个 servletcontext 一个全局共享数据
6websocketspring websocket每个 websocket 连接一个websocket 会话
7refreshspring cloud配置刷新时重建动态配置
8globalsessionportlet全局会话一个portlet 应用(旧版)

六、作用域的选择依据

场景推荐作用域理由
service、dao、controllersingleton无状态,共享安全
有状态的对象prototype隔离状态
请求上下文request每个请求独立
用户登录信息session每个用户独立
全局计数器application全应用共享
websocket 会话websocket每个连接独立
动态配置refresh配置变更时刷新
线程隔离自定义 thread每个线程独立

七、注意事项

1. web 作用域需要代理

requestsessionapplicationwebsocket 作用域的 bean 注入到 singleton bean 时,必须配置 proxymode,否则会报 scope 'xxx' is not active 错误。

2. 作用域名称大小写

spring 的作用域名称是区分大小写的。singleton 不能写成 singletonprototype 不能写成 prototype

3. 自定义作用域需要注册

自定义作用域必须先通过 customscopeconfigurer 注册到容器,才能在 @scope 中使用。

4. prototype 的销毁不归 spring 管

spring 只创建 prototype bean,不管理销毁。@predestroydisposablebean 对 prototype bean 不生效。

5. refresh 依赖 spring cloud

refresh 作用域不是 spring framework 自带的,需要引入 spring cloud context 依赖。

八、总结

分类作用域数量
核心作用域singletonprototype2
web 作用域requestsessionapplicationwebsocket4
扩展作用域refreshglobalsession2
自定义作用域threadtenant不限

spring 一共提供了 8 种可选的作用域(6 个内置 + 2 个扩展),另外还支持自定义。日常开发中最常用的是 singletonprototype,web 项目中会用到 requestsession,spring cloud 项目中会用到 refresh。理解每种作用域的实例范围和生命周期,是设计高质量 spring 应用的基础。

到此这篇关于spring 中完整的 scope 选项实例详解的文章就介绍到这了,更多相关spring scope 选项内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

您想发表意见!!点此发布评论

推荐阅读

MyBatis流式查询之ResultHandler处理海量数据的完整教学

09-21

C 语言结构体如何把相关数据组织成一个整体

09-21

深度解析SpringBoot中启动参数的配置与优化

09-21

浅谈Java线程池用错参数

09-21

Spring Bean作用域详解之单例、原型、请求与会话的区别对比分析

09-20

SpringBoot+Calcite实现跨库查询功能的示例代码

09-21

猜你喜欢

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论