Spring實戰(七)Bean 的作用域
阿新 • • 發佈:2018-01-28
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 的作用域