1. 程式人生 > >Spring實戰(七)Bean 的作用域

Spring實戰(七)Bean 的作用域

targe app value aop get java ppi component size

  1、Spring中bean 的多種作用域

  • 單例(Singleton):整個應用中只創建一個bean 的實例,Spring默認創建單例的bean;
  • 原型(Prototype):每次註入or通過Spring應用上下文獲取時,創建一個新的bean實例;
  • 會話(Session):在web應用中,為每個會話創建一個bean實例,例如用戶購物車的bean;
  • 請求(Request):在web應用中,為每個請求創建一個bean實例;

  

  2、設置會話(Session)作用域

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

  3、購物車場景中的作用域代理——延遲註入請求和會話作用域的bean。

  假設將ShoppingCart bean註入到單例StoreService bean的Setter方法中:

@Component
public class StoreService{
    public void setShoppingCart(ShoppingCart shoppingCart){
        this.shoppingCart=shoppingCart;
    }
  ...     
}

  系統中每個用戶擁有一個ShoppingCart實例,我們並不想讓Spring註入某個固定的ShoppingCart實例到StoreService中,我們希望的是當StoreService處理購物車功能時,它使用的ShoppingCart恰好是當前會話對應的哪一個。

  Spring會註入一個到ShoppingCart bean的代理,而不是一個實際的ShoppingCart bean。這個代理會暴露與ShoppingCart相同的方法,所以StoreService會認為它就是一個購物車。

  而當實際調用ShoppingCart中的方法時,代理會進行懶解析並將調用委托給會話作用域內的真正的ShoppingCart bean!!

  同樣,請求作用域的bean也會面臨相同的裝配問題,也可以通過註入作用域代理解決。

  4、作用域代理——延遲註入請求和會話作用域的bean

  上面我們使用接口來作為作用域代理,其實也可以使用具體類。

  此時,Spring必須使用CGLib來生成基於類的代理:

 proxyMode=ScopedProxyMode.TARGET_CLASS

  5、XML中聲明作用域代理

<bean id="cart" class="xx.xxx.ShoppingCart" scope="session">
    <aop:scoped-proxy />
</bean>

  <aop:scoped-proxy>即告訴Spring使為bean創建一個作用域代理,切默認使用CGLib創建目標類的代理。

  我們也可以通過設置來生成基於接口的代理:

<bean id="cart" class="xx.xxx.ShoppingCart" scope="session">
    <aop:scoped-proxy proxy-target-class="false" />
</bean>

  

Spring實戰(七)Bean 的作用域