bean的作用域


Spring作用域定义

默认情况下,Spring应用上下文中的bean都是以单例(singleton)的形式创建的。

Spring定义了多种作用域,可以基于这些作用域创建bean:

  • 单例(Singleton):在整个应用中,只创建bean一个实例。
  • 原型(Prototype):在每次注入或Spring应用上下文获取的时候,都会创建一个新的bean实例。
  • 会话(Session):在Web应用中,为每个会话创建一个bean实例。
  • 请求(Request):在Web应用中,为每个请求创建一个bean实例。

1.组件扫描的方式

@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class NotePad {
}

2.Java配置的方式

@Bean
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public NotePad notePad(){
    return new NotePad();
}

3.XML配置的方式

<bean id="notePad" class="com.ql.NotePad" scope="prototype"/>

使用会话和请求作用域

在Web应用中,如果能够实例化会话和请求范围内共享的bean,将是非常有价值的事情。如在电子商务应用中,可能用一个bean代表购物车。如果该bean是单例,就会导致导致所有用户都会向同一个购物车添加商品。如果购物车是原型作用域,那么在应用中某个地方向购物车添加商品,在应用的另一个地方可能就用不了。

就购物车的bean来说,会话作用域是最合适的:

@Component
@Scope(value = WebApplicationContext.SCOPE_SESSION,
        proxyMode = ScopedProxyMode.INTERFACES
)
public class ShoppingCart {
}

@Scopevalue设置成session。另一个属性proxyMode设置为ScopedProxyMode.INTERFACES,这个属性解决了将会话或请求作用域的bean注入到单例bean中所出现的问题。以下是该属性解决的问题场景。

假如要把ShoppingCartbean注入到StoreService单例bean的set方法中,如下:

@Component
public class StoreService {

    private ShoppingCart shoppingCart;

    public void setShoppingCart(ShoppingCart shoppingCart) {
        this.shoppingCart = shoppingCart;
    }
}

因为StoreService是一个单例的bean,会在Spring应用上下文加载的时候创建。当它创建的时候,Spring会试图将ShoppingCartbean注入到set方法中。但是ShoppingCartbean是会话作用域,此时并不存在。知道某个用户进入系统,创建会话之后,才会出现ShoppingCart实例。

另外,多个会话产生多个ShoppingCart实例,我们希望StoreService使用的ShoppingCart实例是当前会话的。

Spring并不会将实际的ShoppingCartbean注入到StoreService中,Spring会注入一个到ShoppingCartbean的代理,如下图。这个代理会暴露与ShoppingCart相同的方法,当StoreService调用ShoppingCart的方法时,代理会对其进行懒解析并将调用委托给会话作用域内真正ShoppingCartbean。

会话作用域代理


以上


文章作者: Qliang
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Qliang !
评论
 上一篇
SpringMVC SpringMVC
一、跟踪Spring MVC请求 请求的第一站是Spring的DispatcherServlet,DispatcherServlet查询一个或多个处理器映射(Handler Mappering),处理映射器会根据请求携带的URL信息来决策
2019-03-26
下一篇 
bean的生命周期 bean的生命周期
bean的生命周期 在传统的Java应用中,bean的生命周期很简单。使用new进行bean实例化,然后该bean就可以使用了。一旦该bean不再被使用,则由Java自动进行垃圾回收。 Spring容器中的bean的生命周期就复杂得多。以
2019-03-26
  目录