等闲识得东风面,万紫千红总是春。
![89f4ef060470fb8d1b2ef18d6afd6a46.png](https://i-blog.csdnimg.cn/blog_migrate/b74d93db0183f97438992ed83ddc99c5.jpeg)
概述
在Spring框架中,我们可以在六个内置的spring bean作用域中创建bean,还可以定义bean范围。在这六个范围中,只有在使用支持Web的applicationContext时,其中四个可用。singleton和prototype作用域可用于任何类型的ioc容器。
Spring Bean作用域类型
在Spring中,可以使用spring中的 @Scope注解定义bean的作用域。下面我们已经列出这六个在Spring应用程序上下文中使用的内置bean作用域。这些相同的作用域也适用于spring boot bean作用域。
SCOPE描述singletonspring IoC容器存在一个bean对象实例。prototype与单例相反,每次请求bean时,它都会创建一个新实例。request在HTTP请求(Request) 的完整生命周期中,将创建并使用单个实例。 只适用于web环境中Spring ApplicationContext中有效。session在HTTP会话(Session) 的完整生命周期中,将创建并使用单个实例。 只适用于web环境中Spring ApplicationContext中有效。application将在ServletContext的完整生命周期中创建并使用单个实例。只适用于web环境中Spring ApplicationContext中有效。websocket在WebSocket的完整生命周期中,将创建并使用单个实例。 只适用于web环境中Spring ApplicationContext中有效。
单例作用域
singleton是spring容器中bean的默认作用域。它告诉容器仅创建和管理一个bean类实例。该单个实例存储在此类单例bean的缓存中,并且对该命名bean的所有后续请求和引用都返回该缓存的实例。
使用Java配置的单例作用域bean的示例:
@Component@Scope("singleton") //可以省略,默认即是singletonpublic class BeanClass {}
使用XML配置的单例作用域bean的示例:
//or
原型作用域
每次应用程序对Bean进行请求时,原型作用域都会创建一个新的Bean实例。
您应该知道,销毁bean生命周期方法不调用原型作用域bean,只调用初始化回调方法。因此,作为开发人员,您要负责清理原型作用域的bean实例以及其中包含的所有资源。
原型bean范围的Java配置示例:
@Component@Scope("prototype")public class BeanClass {}
原型bean范围的XML配置示例:
通常,您应该为所有有状态bean使用原型范围,为无状态bean使用单例范围。
要在请求、会话、应用程序和websocket范围内使用bean,您需要注册RequestContextListener或RequestContextFilter.
request作用域
在请求范围中,容器为每个HTTP请求创建一个新实例。因此,如果服务器当前处理50个请求,那么容器最多可以有50个bean类的单独实例。对一个实例的任何状态更改对其他实例都是不可见的。一旦请求完成,这些实例就会被销毁。
request请求bean范围的Java配置示例:
@Component@Scope("request")public class BeanClass {}//or@Component@RequestScopepublic class BeanClass {}
request请求bean范围的XML配置示例:
session作用域
在会话范围中,容器为每个HTTP会话创建一个新实例。因此,如果服务器有20个活动会话,那么容器最多可以有20个bean类的单独实例。在单个会话生命周期内的所有HTTP请求都可以访问该会话范围内相同的单个bean实例。
在会话范围内,对一个实例的任何状态更改对其他实例都是不可见的。一旦会话在服务器上被销毁/结束,这些实例就会被销毁。
session请求bean范围的Java配置示例:
@Component@Scope("session")public class BeanClass {}//or@Component@SessionScopepublic class BeanClass {}
session请求bean范围的XML配置示例:
application作用域
在应用程序范围内,容器为每个web应用程序运行时创建一个实例。它几乎类似于单例范围,只有两个不同之处。即:
- 应用程序作用域bean是每个ServletContext的单例对象,而单例作用域bean是每个ApplicationContext的单例对象。请注意,单个应用程序可能有多个应用程序上下文。
- 应用程序作用域bean作为ServletContext属性可见。
application bean范围的Java配置示例:
@Component@Scope("application")public class BeanClass {}//or@Component@ApplicationScopepublic class BeanClass {}
application bean范围的XML配置示例:
websocket作用域
WebSocket协议支持客户端和远程主机之间的双向通信,远程主机选择与客户端通信。WebSocket协议为两个方向的通信提供了一个单独的TCP连接。这对于具有同步编辑和多用户游戏的多用户应用程序特别有用。
在这种类型的Web应用程序中,HTTP仅用于初始握手。如果服务器同意,服务器可以以HTTP状态101(交换协议)进行响应。如果握手成功,则TCP套接字保持打开状态,客户端和服务器都可以使用该套接字向彼此发送消息。
websocket bean范围的Java配置示例:
@Component@Scope("websocket")public class BeanClass {}
websocket bean范围的XML配置示例:
请注意,websocket范围内的bean通常是单例的,并且比任何单独的WebSocket会话寿命更长。
自定义线程作用域
Spring还使用类SimpleThreadScope提供了非默认线程作用域。若要使用此作用域,必须使用CustomScopeConfigurer类将其注册到容器。
对bean的每个请求都将在同一线程中返回相同的实例。
线程bean范围的Java配置示例:
@Component@Scope("thread")public class BeanClass {}
线程bean范围的xml配置示例:
总结
Spring framework提供了六个Spring bean作用域,每个作用域内的实例具有不同的生命周期跨度。作为开发人员,我们必须明智地选择任何容器管理bean的范围。同样,当具有不同作用域的bean相互引用时,我们必须做出明智的决定。
请记住以上给出的所有信息来回答任何spring bean作用域的面试问题。