Spring Bean作用域

时间:2020-01-09 10:44:30  来源:igfitidea点击:

使用Spring bean定义,Spring容器不仅实例化bean并连接其依赖关系,还提供了从特定bean定义创建的对象的范围。 Spring框架对六个Spring bean范围提供了内置支持。在这六个bean范围中,只有当我们使用可识别Web的ApplicationContext时,才有四个可用。我们还可以创建自定义范围。

Spring bean支持的作用域(范围)

  • 单例作用域–为每个Spring IoC容器创建一个与bean定义相对应的单个对象实例。 Singleton范围是默认的bean范围。

  • 原型作用域–每次从Spring容器请求bean时都会创建一个新的对象实例。

  • 请求作用域–为每个HTTP请求创建一个新的bean实例。此Spring bean范围仅在可感知网络的Spring ApplicationContext的上下文中有效。

  • 会话作用域–单个bean实例的范围是HTTP会话的生命周期。该范围仅在可感知网络的Spring ApplicationContext的上下文中有效。

  • 应用程序作用域–将单个bean定义范围限定为ServletContext的生命周期。该范围仅在可感知网络的Spring ApplicationContext的上下文中有效。

  • Websocket作用域–将单个bean定义的范围扩展到WebSocket的生命周期。该范围仅在可感知网络的Spring ApplicationContext的上下文中有效。

Spring Bean的单例范围

当我们将一个bean限定为一个单例时,Spring容器将为该bean定义所定义的对象创建一个实例。对ID与该bean定义匹配的ID的所有请求都将导致该特定的bean实例由Spring容器返回。

Singleton作用域是Spring中的默认作用域,如果我们未在bean定义中提供bean作用域,则将bean作为作用域创建。

请注意,Spring单例的范围是每个容器和每个bean。尽管Spring容器创建了该bean定义所定义的类的一个实例,并且只有一个实例,但是我们仍然可以创建该bean的其他对象,这些对象不受Spring容器的管理。

单例作用域Bean的XML配置示例

<bean id="abcBean" class="com.theitroad.BeanService" scope="singleton"/>

它等同于以下定义,因为单例作用域是默认作用域

<bean id="abcBean" class="com.theitroad.BeanService"/>

使用@Scope注释定义单例作用域的bean

@Service
@Scope("singleton")
public class BeanService{
 ...
 ...
}

Spring bean原型范围

当一个bean的作用域是原型时,每次请求该特定bean时都会创建一个新的bean实例。
Spring不能管理原型Bean的完整生命周期。对于原型作用域的bean,将调用生命周期回调方法,但不会调用已配置的销毁生命周期回调方法。客户端代码负责清理原型作用域内的对象并释放原型bean所拥有的资源。
原型范围内的bean-的XML配置示例

<bean id="abcBean" class="com.theitroad.BeanService" scope="prototype"/>

使用注解定义原型作用域bean

@Service
@Scope("prototype")
public class BeanService{
 ...
 ...
}

Request作用域

对于请求范围的bean,Spring容器为每个HTTP请求创建一个新的bean实例。这些实例特定于单个请求,并且在请求完成处理后,实例将被销毁。

请求范围的bean-的XML配置示例

<bean id="abcBean" class="com.theitroad.BeanService" scope="request"/>

如果要使用注释,则可以使用@RequestScope注释将组件分配给请求范围,也可以使用@Scope(WebApplicationContext.SCOPE_REQUEST)。

@RequestScope
@Service
public class BeanService{
 ...
 ...
}

Session作用域

对于会话范围的bean,Spring容器在单个HTTP Session的生存期内创建该bean的新实例。这意味着bean的作用域位于HTTP会话级别,并且在丢弃该特定HTTP会话时将其丢弃。

会话范围的bean-的XML配置示例

<bean id="abcBean" class="com.theitroad.BeanService" scope="session"/>

如果要使用注释,则可以使用@SessionScope注释将组件分配给请求范围,也可以使用@Scope(WebApplicationContext.SCOPE_SESSION)。

@SessionScope
@Service
public class BeanService{
 ...
 ...
}

Application作用域

对于应用程序范围的bean,Spring容器为整个Web应用程序创建一次bean的新实例。这意味着bean的作用域位于ServletContext级别,并存储为常规ServletContext属性。

应用程序范围的bean-的XML配置示例

<bean id="abcBean" class="com.theitroad.BeanService" scope="application"/>

如果要使用注释,则可以使用@ApplicationScope注释将组件分配给请求范围,也可以使用@Scope(WebApplicationContext.SCOPE_APPLICATION)。

@ApplicationScope
@Service
public class BeanService{
 ...
 ...
}

Spring中的WebSocket bean作用域

Spring框架提供了一个WebSocket API,可用于编写处理WebSocket消息的客户端和服务器端应用程序。 WebSocket范围的bean通常是单例的,并且比任何单独的WebSocket会话的生存期更长。因此,我们需要对作用域WebSocket的bean使用作用域代理模式。

@Component
@Scope(scopeName = "websocket", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class MyBean {
 ...
 ...
}

对于Spring bean范围请求,会话,应用程序和Websocket,我们需要注册
org.springframework.web.context.request.RequestContextListener。对于Servlet 3.0+,可以使用WebApplicationInitializer接口以编程方式完成此操作。如果我们使用的是Servlet 2.5 Web容器,则必须通过在Web应用程序的web.xml文件中添加以下声明来显式地完成此注册:

<web-app>
  ...
  <listener>
    <listener-class>
        org.springframework.web.context.request.RequestContextListener
    </listener-class>
  </listener>
  ...
</web-app>