Bean 的作用域有哪些?

Spring 中 Bean 的作用域通常有下面几种:

  • singleton : IoC 容器中只有唯一的 bean 实例。Spring 中的 bean 默认都是单例的,是对单例设计模式的应用。
  • prototype : 每次获取都会创建一个新的 bean 实例。也就是说,连续 getBean() 两次,得到的是不同的 Bean 实例。
  • request (仅 Web 应用可用): 每一次 HTTP 请求都会产生一个新的 bean(请求 bean),该 bean 仅在当前 HTTP request 内有效。
  • session (仅 Web 应用可用) : 每一次来自新 session 的 HTTP 请求都会产生一个新的 bean(会话 bean),该 bean 仅在当前 HTTP session 内有效。
  • application/global-session (仅 Web 应用可用):每个 Web 应用在启动时创建一个 Bean(应用 Bean),该 bean 仅在当前应用启动时间内有效。
  • websocket (仅 Web 应用可用):每一次 WebSocket 会话产生一个新的 bean。
<think>嗯,用户之前已经问过关于Bean的基本概念,现在接着问Spring Bean作用域。我需要先回顾一下之前的问题,确保回答连贯。用户可能正在学习Spring框架,需要了解Bean的不同作用域来更好地管理应用中的对象生命周期。 首先,我要列出Spring Bean的所有作用域,但得确认版本。Spring默认的作用域在文档里是五个还是六个?记得从Spring 3开始有request、session、application,还有websocket作用域,但可能用户用的是较新的版本,所以得检查最新的作用域是否有变化。 默认的作用域应该是单例(singleton)和原型(prototype),而web相关的如request、session、application和websocket。要确保不遗漏这些。然后,每个作用域需要简单解释,并给出使用场景的例子,这样用户更容易理解。 用户可能想知道如何配置这些作用域,所以需要提到注解方式,比如@Scope,或者XML配置。同时,需要指出常见的错误,比如在单例Bean中注入原型Bean可能导致的问题,以及如何解决,比如用provider或者方法注入。 另外,用户可能对作用域的实际应用场景不太清楚,所以举一些例子,比如用户登录信息用session作用域,HTTP请求相关的数据用request作用域,这样更具体。 还要注意提到自定义作用域的可能性,虽然高级,但用户可能有兴趣了解扩展性。不过这部分可以简要带过,避免信息过载。 最后,检查是否有遗漏的作用域,确认Spring的最新版本是否有新增或变化。比如,application作用域对应的是ServletContext,而globalSession在Portlet环境中使用,但现在Portlet可能不太常用,是否需要提到?可能需要说明它适用于Portlet应用,但多数情况下可能用不到,避免混淆用户。 总结一下,回答的结构应该是先总述作用域的作用,然后分点列出每个作用域,解释其含义和使用场景,最后给出配置方式和注意事项。确保语言简洁明了,符合用户的中文理解习惯。</think>Spring Bean作用域定义了Bean在容器中的生命周期和可见范围。以下是Spring支持的**6种核心作用域**及其适用场景: --- ### **1. 单例作用域(Singleton,默认)** - **定义**:整个容器中仅存在一个实例,所有请求共享同一个Bean。 - **适用场景**:无状态的工具类、配置类、服务类等。 - **配置方式**: ```java @Scope("singleton") @Bean public MyBean myBean() { ... } ``` --- ### **2. 原型作用域(Prototype)** - **定义**:每次请求都创建新实例。 - **适用场景**:需要维护独立状态的场景(如用户会话数据)。 - **注意事项**:需自行管理销毁逻辑(容器不负责原型Bean的销毁)。 ```java @Scope("prototype") ``` --- ### **3. 请求作用域(Request)** - **定义**:每个HTTP请求创建一个新实例,请求结束后销毁。 - **适用场景**:HTTP请求相关的数据(如表单提交参数)。 - **配置要求**:需在Web环境中使用(如Spring MVC)。 ```java @Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS) ``` --- ### **4. 会话作用域(Session)** - **定义**:每个用户会话(Session)创建一个实例,会话过期后销毁。 - **适用场景**:用户登录信息、购物车数据等。 ```java @Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS) ``` --- ### **5. 应用作用域(Application)** - **定义**:整个Web应用共享一个实例(类似单例,但绑定到ServletContext生命周期)。 - **适用场景**:全局缓存、共享资源。 ```java @Scope(value = WebApplicationContext.SCOPE_APPLICATION) ``` --- ### **6. WebSocket作用域(WebSocket)** - **定义**:每个WebSocket会话创建一个实例,会话关闭后销毁。 - **适用场景**:实时通信(如聊天室消息管理)。 ```java @Scope(scopeName = "websocket") ``` --- ### **扩展:自定义作用域** 通过实现`Scope`接口可定义自定义作用域(如线程作用域),需注册到容器: ```java ConfigurableBeanFactory.registerScope("customScope", new CustomScope()); ``` --- ### **作用域配置方式对比** | 方式 | 注解示例 | XML配置示例 | |--------|----------------------------------|-----------------------------------| | 单例 | `@Scope("singleton")` | `<bean scope="singleton"/>` | | 原型 | `@Scope("prototype")` | `<bean scope="prototype"/>` | | 请求 | `@RequestScope` | `<bean scope="request"/>` | | 会话 | `@SessionScope` | `<bean scope="session"/>` | --- ### **常见问题** 1. **单例Bean中注入原型Bean** - 问题:单例Bean依赖的原型Bean不会刷新。 - 解决:使用`Provider`或方法注入: ```java @Autowired private Provider<PrototypeBean> prototypeBeanProvider; ``` 2. **代理模式(ProxyMode)** 在Web作用域中需设置`proxyMode`以延迟初始化(如`TARGET_CLASS`表示使用CGLIB代理)。 --- **总结**:选择合适的作用域需结合具体业务场景,避免因作用域误用导致内存泄漏或状态混乱。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值