1、spring定義了多種作用域,可以基於這些作用域創建bean: 單例(Singleton):在整個應用中,只創建一次bean實例 原型(Prototype):每次註入或者通過上下文獲取bean時候,都會創建一個新的bean實例 會話(Session):在Web應用中,為每個會話創建一個bean實 ...
1、spring定義了多種作用域,可以基於這些作用域創建bean:
- 單例(Singleton):在整個應用中,只創建一次bean實例
- 原型(Prototype):每次註入或者通過上下文獲取bean時候,都會創建一個新的bean實例
- 會話(Session):在Web應用中,為每個會話創建一個bean實例
- 請求(Request):在Web應用中,為每個請求創建一個bean實例
2、配置bean作用域
- 基於註解
@Component @Scope("prototype") public class Person1 { //... }
- 基於XML
<bean id="person1" class="com.cn.pojo.Person1" scope="prototype"></bean>
3、單例作用域
在預設情況下,spring容器中的所有bean都是單例的。單例的bean如果需要保持一些狀態,那麼重用是不安全,因為對象會被污染。
4、原型作用域
5、會話作用域
在典型的電子商務系統中,可能會有一個bean代表用戶的購物車,如果購物車是單例的話,那麼將會導致所有的用戶都向同一個購物車中添加商品;如果購物車是原型的話,那麼在應用的某個地方向購物車添加了商品,在應用給的另外一個地方可能就不可用了,因為註入的是原型作用域的購物車。此時,會話作用域最合適。
@Component @Scope(value = "session",//作用域為會話,spring會為應用中的每個會話創建一個cart
proxyMode = ScopedProxyMode.INTERFACES)//指定了代理模式 public class Cart { //... }
proxyMode 的值由枚舉類指定了可選範圍:
public enum ScopedProxyMode { DEFAULT, NO, INTERFACES, //代理介面 TARGET_CLASS; //基於CGLisb生成基於類的代理 private ScopedProxyMode() { } }
Cart應用到下麵類中
@Component public class StoreService { @Autowired private Cart cart; //... }
在web應用中StoreService 是單例的,Cart是會話的,StoreService 中註入了Cart。
實際上由於proxyMode的作用,並不是直接註入了Cart bean,而是會註入一個到Cart bean的代理。這個代理會暴露Cart相同的方法,所以StoreService 會認為它是一個購物車。當StoreService 調用Cart的方法時,代理會對其進行藍解析並將調用委托給會話作用域內真正的Cart bean
6、請求作用域
與會話作用域一樣通過作用域代理的方式使用