天天看點

Spring中bean的scope用法

Spring中bean的scope有六種:singleton,prototype,request,session,global session,application。此外,使用者還可以自定義scope。還有一種scope是thread類型的,但是預設沒有啟用。

singleton是預設的scope。全局範圍内隻有一個bean被托管,所有對它的請求或者引用都是指向的這個Spring容器内的唯一執行個體。

換句話說,當你定義了一個singleton的bean以後,Spring 的 IoC容器會建立且僅建立一個對象的執行個體。這個執行個體會儲存在singleton bean的緩存中,所有的請求和引用都傳回這個緩存中的對象。

Spring的singletonbean概念不同于24種設計模式(Gang of Four, GoF)中的單例模式,單例模式在編碼中定義了對于每一個 ClassLoader 都隻會産生唯一執行個體,而Spring的singleton bean是在每一個Spring容器中産生唯一bean。

要使用xml定義bean,可以這樣

<bean id="accountService" class="com.foo.DefaultAccountService"/>
或
<bean id="accountService" class="com.foo.DefaultAccountService" scope="singleton"/>      

 明确指明singleton的scope有些多餘,不過可以接受。

prototype的scope是另一種常用的bean,是和singleton相對的。對于每一次請求該bean,spring都會建立一個新的執行個體。prototype的是有狀态bean,singleton是無狀态bean。

使用xml建立方式如下

<bean id="accountService" class="com.foo.DefaultAccountService" scope="prototype"/>      

 不同于其他scope,Spring不會管理prototype的bean。盡管所有scope的bean初始化回調都會被調用,但是對于prototype的bean,Spring不會調用其銷毀回調。必要的時候,使用者需要同代碼來銷毀其。

request和session已經global session都是web模式下才能使用的。如果使用ClassPathXmlApplicationContext初始化容器,會報錯IllegalStateException。

要是有這些scope,需要做一些額外的配置(上述兩種不需要)。在Spring MVC中,如果通過DispatcherServlet 或 DispatcherPortlet 過濾請求就不需要更多修改了,因為它們包含了相關的狀态。

如果沒有使用Spring 的MVC,比如使用了Struts,對于Servlet 2.5需要注冊org.springframework.web.context.request.RequestContextListener。對于Servlet 3.0以上,可以通過WebApplicationInitializer代碼配置這個監聽器。在web.xml中配置方式如下:

<web-app>
    ...
    <listener>
        <listener-class>
            org.springframework.web.context.request.RequestContextListener
        </listener-class>
    </listener>
    ...
</web-app>      

 如果容器不支援這種方式,可以使用過濾器RequestContextFilter:

<web-app>
    ...
    <filter>
        <filter-name>requestContextFilter</filter-name>
        <filter-class>org.springframework.web.filter.RequestContextFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>requestContextFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    ...
</web-app>      

application的scope和singleton的很像,不過有兩點差別:application的是對于每個ServletContext産生一個執行個體而非每個Spring容器;另外它是ServletContext可見的。