1. 程式人生 > >【Spring學習19】作用域:使用代理

【Spring學習19】作用域:使用代理

接上篇

請這樣做

如果想把一個web作用域的Bean注入到另一個週期長的作用域的Bean中(比如單例的bean),就需要選擇注入一個AOP代理來替換這個web作用域Bean。在定義時,web作用域的Bean都需要宣告使用代理模式:配置中加上<aop:scoped-proxy/>元素

官方文件的例子:

<!-- 一個HTTP session作用域的Bean 作為代理暴露出去 -->
    <bean id="userPreferences" class="com.foo.UserPreferences" scope="session">
        <!--指示容器代理這個Bean -->
<aop:scoped-proxy/> </bean> <!--一個單例Bean注入一個代理Bean --> <bean id="userManager" class="com.foo.UserManager"> <!-- 實際使用的是userPreferences的代理物件 --> <property name="userPreferences" ref="userPreferences"/> </bean>

為什麼要這樣做?

上例中,HTTP Session作用域的userPreferences bean注入給單例userManger bean。因為userManager bean是單例的,即每個容器只會例項化一個,所以它的依賴物件userPreferences bean也僅會注入一次。這樣下來,userManagerbean只能操作相同的userPreferences物件,就是初始化時注入的那一個。

將一個短生命週期作用域bean注入給長生命週期作用域bean都會存在此類問題。
我們期望的是userManager物件中的userPreferences beans與session同生命週期和同作用域。

在userPreferences bean配置中加入<aop:scoped-proxy/>後,容器將建立一個代理物件,該物件擁有和UserPreferences完全相同的public介面並暴露。代理物件每次呼叫時會從 Session範圍內獲取真正的UserPreferences物件,而userManager類卻不知道。