Spring裝配Bean(六)Bean的作用域
在預設情況下,Spring應用上下文中所有bean都是作為以單例的形式建立的。也就是說,不管給定的一個bean被注入到其他bean多少次,每次所注入的都是同一個例項
在大多數情況下,單例bean時很理想的方案。有時候存在,所使用的類是易變的,對這些類的bean進行重用可能就不安全,例如購物車bean如果是單例的話,每個使用者都向一個購物車中新增商品,這就有問題了
Spring定義了多種作用域,可以基於這些作用域建立bean,包括:
1> 單例(Singleton):在整個應用中,只建立bean的一個例項
2> 原型(Prototype):每次注入或者通過Spring應用上下文獲取的時候,都會去建立一個新的Bean
3> 會話(Session):在Web應用中,為每個會話建立一個Bean例項。
4> 請求(Request):在Web應用中,為每個請求建立一個Bean例項
* JavaConfig中設定作用域
@Scope註解和@Component或@Bean一起使用
@Bean
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public CDPlayer cdplayer(){
return new CDPlayer(this.cd);
}
@Component
@Qualifier("compactDisc2")
@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
public class SgtPeppers implements CompactDisc {
}
這裡,使用ConfigurableBeanFactory類的SCOPE_PROTOTYPE常量設定了原型作用域,當然也可以使用@Scope("prototype"),但是SCOPE_PROTOTYPE常量更加安全並且不易出錯。
* XML中配置Bean的作用域
<bean id="compactDisc1" class="com.erong.service.SgtPeppers" scope="prototype">
<constructor-arg name="title" value="遙遠的ren"></constructor-arg>
<constructor-arg name="artist" value="big ben..."></constructor-arg>
</bean>
* 使用會話和請求作用域
在Web應用中,如果能夠例項化在會話和請求範圍內共享的Bean,將是很有價值的事情。
例如,在典型的電子商務應用中,可能會有一個Bean代表使用者的購物車。如果購物車是單例的,那麼就會導致多個使用者向同一個購物車中新增商品,如果購物車是原型的,在一個位置設定了,購物車的屬性(商品名稱,種類..),在另一個地方通過注入使用的時候,將拿不到剛才那個Bean,而是一個新建立的Bean,這就存在問題了。
* JavaConfig中宣告作用域代理
就購物車bean來說,會話作用域最合適
@Component
@Scope(value=WebApplicationContext.SCOPE_SESSION,
proxyMode=ScopedProxyMode.INTERFACES
)
public interface ShoppingCart {
}
我們將value設定成WebApplicationContext中的SCOPE_SESSION常量。將告訴Spring為Web應用中的每個會話建立Bean。
注意的是,@Scope同時還有一個proxyMode屬性,被設定為了ScopedProxyMode.INTERFACES. 解決了將會話或請求作用域的bean注入到單例bean中遇到的問題.
現在將ShoppingCart注入到單例StoreService bean的setter方法中,如下所示:
@Component
@Qualifier("storeService")
public class StoreService {
private ShoppingCart sc ;
@Autowired
@Qualifier("sc")
public void setShoppingCart(ShoppingCart sc){
this.sc = sc;
}
}
StoreService是單例的,建立這個Bean的時候,Spring上下文回去嘗試自動注入ShoppingCart這個Bean,但是隻要是使用者還沒有訪問系統,這個bean就不會建立。
另外,對於每個使用者,都會去建立ShoppingCart這個Bean,也就是StoreService注入的Bean,不是唯一的,我們希望的是注入的購物車Bean,剛好是當前會話的那個。
Spring實際上不將將真正的ShoppingCart Bean注入到StoreService,而是注入它的代理,到具體使用到ShoppingCart Bean才會去,進行懶解析找到實際的Bean。
proxyMode屬性設定為ScopedProxyMode.INTERFACES,這表明這個代理將要實現ShoppingCart介面,並將呼叫委託給實現bean.
如果ShoppingCart是介面而不是類,這是可以的(也是最為理想的代理模式),但如果shoppingCart是一個具體的類的話,Spring 無法建立基於介面的代理了,此時,必須使用CGLIB生成基於類的代理。將proxyMode屬性設定為ScopedProxyMode.
TARGET_CALSS
* 在XML中宣告作用域代理
<bean id="helloWorld" class="com.erong.service.HelloWorld" scope="session">
<aop:scoped-proxy proxy-target-class="false"/>
</bean>
預設是採用cglib生成代理物件,如果將proxy-target-class="false" 將表示基於介面生成代理物件
相關文章
- Bean的自動裝配及作用域Bean
- Spring Bean作用域SpringBean
- Spring bean 裝配SpringBean
- Spring中Bean的作用域SpringBean
- Spring 當中的Bean 作用域SpringBean
- Spring裝配Bean(四)SpringBean
- Spring裝配Bean(一)SpringBean
- Spring裝配Bean(二)SpringBean
- 二、Spring裝配BeanSpringBean
- Spring 框架基礎(02):Bean的生命週期,作用域,裝配總結Spring框架Bean
- Spring中Bean的作用域有哪些?SpringBean
- Spring學習(二)Bean 作用域SpringBean
- Spring IOC 一——Spring容器裝配BeanSpringBean
- spring bean的作用域和生命週期SpringBean
- 初識Spring —— Bean的裝配(一)SpringBean
- 初識Spring —— Bean的裝配(二)SpringBean
- Spring-04 Bean的自動裝配SpringBean
- Springboot中的Bean作用域Spring BootBean
- 《Spring》(六)---- Bean的scopeSpringBean
- Spring裝配Bean(七) Spring的執行時注入SpringBean
- bean 的自動裝配Bean
- 詳解Spring中Bean的作用域與生命週期SpringBean
- Spring入門(二):自動化裝配beanSpringBean
- Spring入門(三):通過JavaConfig裝配beanSpringJavaBean
- Spring:Bean的scope作用域案例講解以及Bean之間的依賴和繼承(3)SpringBean繼承
- Spring中建立帶原型作用域bean5種方法Spring原型Bean
- SpringBoot(14)—註解裝配BeanSpring BootBean
- 【面試普通人VS高手】Spring 中Bean的作用域有哪些?面試SpringBean
- Spring入門(六):條件化的beanSpringBean
- [Spring]BeanSpringBean
- Spring Bean的3種裝配方式SpringBean
- @Configuration, @Bean 註解的作用Bean
- Spring Bean容器SpringBean
- 【Spring】Bean管理SpringBean
- Spring裝配Bean(五)profile註解和解決自動注入的歧義性SpringBean
- Spring Bean 綜述SpringBean
- spring boot factory beanSpring BootBean
- 淺談Spring BeanSpringBean