spring中bean作用域默认为单例,@scope可设为singleton(共享实例)、prototype(每次获取新建)、request/session/application(web环境)。单例由容器管理生命周期,prototype不调用销毁回调;多例注入单例需代理或@lookup避免“假多例”。

在 Spring 中,Bean 的作用域通过 @Scope 注解设置,最常用的是单例(Singleton)和多例(Prototype)两种。默认就是单例,显式声明可提高可读性;多例需手动指定,每次获取都会新建实例。
单例作用域(Singleton)
同一个 Spring 容器中,该 Bean 只有一个共享实例,所有依赖它的地方都指向同一对象。适用于无状态组件(如 Service、DAO)。
- 默认行为,不加
@Scope就是单例 - 显式写法:
@Scope("singleton")或@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON) - 注意:单例 Bean 依赖的其他单例 Bean 也只初始化一次,整个生命周期由容器管理
多例作用域(Prototype)
每次从容器中获取(context.getBean())都会创建一个新实例,适合有状态或需要隔离数据的场景(如 Web 表单对象、临时上下文)。
- 必须显式声明:
@Scope("prototype")或@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) - 容器只负责创建,不管理其销毁——即不调用
@PreDestroy或执行销毁回调 - 若多例 Bean 注入到单例 Bean 中,注入动作只发生一次(即单例里持有一个固定的多例实例),这不是“每次用都新建”——要解决需用
@Lookup方法或ObjectFactory
Web 环境下的扩展作用域
在 Spring MVC 或 WebFlux 中还可使用请求级、会话级作用域,需配合 Web 相关配置启用:
-
@Scope("request"):每个 HTTP 请求创建一个实例,请求结束即销毁 -
@Scope("session"):每个用户 Session 创建一个实例,Session 失效时销毁 -
@Scope("application"):等价于单例,但绑定到 ServletContext 生命周期 - 使用前确保已启用 Web 作用域支持(Spring Boot 默认已配好;传统 XML 需配置
RequestContextListener或RequestContextFilter)
注意事项与常见误区
@Scope 只对 Spring 管理的 Bean 生效(即被 @Component、@Service 等注解标注,或通过 @Bean 方法注册的)。
-
@Scope在@Bean方法上使用时,作用于该方法返回的 Bean;在类上使用时,作用于该组件类 - 多例 Bean 中如果依赖单例 Bean,没问题;但单例 Bean 中直接持有(非懒加载/非代理)多例 Bean 引用,会导致“假多例”——应改用
@Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)或@Lookup - 自定义作用域需实现
org.springframework.beans.factory.config.Scope接口并注册
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











