引言
在Java编程中spring框架已经使用的非常广泛,如今由spring框架派生的spring周边项目也逐渐流行起来,如spring boot,在现在的微服务里面用的甚多。但是用了这么多spring框架的模块和项目,有些时候还是需要对spring框架的基本知识进行深入了解,这里我讲记录下spring框架中bean的作用域。在Spring框架中,可以在6个内置的范围中创建bean,也可以定义自定义范围。 在这六个范围中,只有在使用Web感知的ApplicationContext时才有四个范围可用。
singleton
和prototype
(单例和多例)作用域 在任何的spring框架IOC容器都可用。
一.spring框架中Bean的作用域类型讲解
下面是六个spring框架中默认可用的作用域作用域类型 | 简介 |
---|---|
singleton (默认单例) |
spring框架的 IoC 容器中只有单个实例。 |
prototype |
与单例相反, 多例会在每次使用他的时候创建一个新的实例. |
request |
在HTTP request的完整生命周期中,将创建并提供一个实例。 只在web感知的Spring ApplicationContext中有效。 |
session |
在HTTP session的整个生命周期中,将创建一个单一的实例并使其可用。 只在web感知的Spring ApplicationContext中有效。 |
application |
在ServletContext的完整生命周期中,将创建并提供一个实例。 只在web感知的Spring ApplicationContext中有效。 |
websocket |
WebSocket的完整生命周期中将创建并提供一个实例。 Only valid in web-aware Spring |
1.1 spring框架singleton(单例) scope(作用域)
singleton
是spring容器中的默认bean作用域。 它告诉容器创建和管理每个容器只有一个bean类的实例。 这个单实例存储在这样的单例bean的缓存中,并且该命名bean的所有后续请求和引用都会返回缓存的实例。下面是一个单例作用域,使用的Java代码配置方式:
@Component
@Scope("singleton")//这个语句其实是多余的 - 单例是默认范围
public class BeanClass {
}
同样,下面是一个基于xml配置的方式:
<!-- 指定单例作用域是多余的 -->
<bean id="beanId" class="com.xqlee.BeanClass" scope="singleton" />
//或者
<bean id="beanId" class="com.xqlee.BeanClass" />
1.2 spring框架prototype(多例)scope(作用域)
prototype
(多例)作用域,每一次请求使用到该bean都会被应用创建一个新的实例。你应该知道销毁bean的生命周期方法并不会调用
prototype
作用域的beans,只有在初始化回调方法的时候调用。因此作为开发人员,应该负责清理prototype
作用域的beans实例和他们挂着的其他资源。Java代码配置的方式的prototype(多例)作用域例子:
@Component
@Scope("prototype")
public class BeanClass {
}
下面是xml的方式:
<bean id="beanId" class="com.xqlee.BeanClass" scope="singleton" />
提示:通常应该使用prototype(多例)在有状态的bean ,singleton(单例)处理无状态的bean
注意:在request, session, application 和 websocket 作用域中使用beans,必须注册RequestContextListener或者RequestContextFilter
1.3 spring框架request scope(作用域)
在request
范围中,容器为每个HTTP请求创建一个新的实例。因此,如果服务器正在处理50个请求,然而容器最多可以创建50个单独bean的实例。 任何状态更改为一个实例,其他实例将不可见。 这些实例一旦请求完成就被销毁。Java代码配置方式例子:
@Component
@Scope("request")
public class BeanClass {
}
//或者
@Component
@RequestScope
public class BeanClass {
}
xml配置例子:
<bean id="beanId" class="com.xqlee.BeanClass" scope="request" />
1.4 spring框架session scope(作用域)
在session
作用域,容器为每个HTTP会话创建一个新的实例。因此,如果服务器有20个活动会话,并且容器最多可以有20个单独的bean类实例。在单个会话生命周期内的所有HTTP请求将有权访问该会话作用域中相同的单个bean实例。任何状态更改为一个实例,其他实例将不可见。 一旦会话被销毁/终止在服务器上,这些实例就被销毁了。
Java代码配置例子:
@Component
@Scope("session")
public class BeanClass {
}
//or
@Component
@SessionScope
public class BeanClass {
}
xml配置例子:
<bean id="beanId" class="com.xqlee.BeanClass" scope="session" />
1.5 spring框架application scope(作用域)
在application
作用域中,容器每个Web应用程序运行时创建一个实例 它几乎类似于单一的范围,只有两个不同之处,即:
application
范围的bean是每个ServletContext
单例,而singleton
范围的bean是每个ApplicationContext单例。 请注意,单个应用程序可以有多个应用程序上下文。application
范围的bean作为一个ServletContext
属性是可见的。
@Component
@Scope("application")
public class BeanClass {
}
//or
@Component
@ApplicationScope
public class BeanClass {
}
xml配置例子:
<bean id="beanId" class="com.leftos.BeanClass" scope="application" />
1.6 spring框架websocket scope(作用域)
WebSocket协议启用客户端和选择与客户端通信的远程主机之间的双向通信。 WebSocket协议为两个方向上的流量提供单个TCP连接。 这对于同时编辑和多用户游戏的多用户应用程序特别有用。在这种类型的Web应用程序中,HTTP仅用于初始握手。 服务器可以响应HTTP状态101(切换协议),如果它同意 - 握手请求。 如果握手成功,则TCP套接字保持打开状态,客户端和服务器都可以使用它来相互发送消息。
java代码配置例子:
@Component
@Scope("websocket")
public class BeanClass {
}
xml配置例子:
<bean id="beanId" class="com.howtodoinjava.BeanClass" scope="websocket" />
请注意,websocket范围的bean通常是单身,比任何单独的WebSocket会话寿命更长。1.7当前线程作用域
Spring框架还提供了一个使用SimpleThreadScope类的非默认thread
作用域。 要使用此范围,您必须使用CustomScopeConfigurer
类将其注册到容器。
<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
<property name="scopes">
<map>
<entry key="thread">
<bean class="org.springframework.context.support.SimpleThreadScope"/>
</entry>
</map>
</property>
</bean>
每个bean的请求都会在同一个线程中返回相同的实例。Java配置例子:
@Component
@Scope("thread")
public class BeanClass {
}
xml配置例子:
<bean id="beanId" class="com.howtodoinjava.BeanClass" scope="thread" />
二.总结
Spring框架提供了六个bean作用域,每个作用域内的实例有不同的生命周期跨度。 作为开发人员,我们必须明智地选择任何容器管理bean的范围。 另外,当不同范围的豆子互相引用时,我们必须做出明智的选择。https://www.syntaxspace.com/article/301.html
评论