天天看點

[Spring] Bean的作用域Scope

文章目錄

    • singleton
    • prototype
    • request
    • session
    • application
    • websocket
    • SimpleThreadScope

Spring

中的對象

scope

屬性表示是對象可以生存的範圍,有以下幾種取值:

singleton

單例作用域,也是

Spring

的預設

scope

值。在整個

IOC

容器的生命周期中,最多隻會建立出一個對象執行個體,任何需要該對象的地方,都是引用的這一個執行個體。

這在設計模式中,就是典型的“單例模式”。

<bean id="accountService" class="com.something.DefaultAccountService"/>

<!-- the following is equivalent, though redundant (singleton scope is the default) -->
<bean id="accountService" class="com.something.DefaultAccountService" scope="singleton"/>
           

prototype

原型作用域,它的意思是每次需要該對象的時候,

IOC

容器都會建立一個新的對象執行個體,不會複用以前建立的對象。

這在設計模式中,就是典型的“原型模式”。

request

請求作用域,這種作用域隻存在于

Spring Web

應用中,是專門針對

http

請求設計的,為每個

http

請求建立新的對象執行個體,并且該執行個體隻在當次請求範圍内有效。

session

會話作用域,這還是隻存在于

Spring Web

應用中的作用域,是針對

cookies-session

機制設計的,對象的生命周期限定在

session

範圍内。

application

應用作用域,這也是針對

Spring Web

應用的,針對的是

Servlet

應用上下文,也就是

ServletContext

對象執行個體,這種作用域就是綁定到這個執行個體上的。

websocket

這種作用域也是針對

Spring Web

應用的,隻不過這裡針對的通信協定是

WebSocket

協定,不是

Http

協定,這兩種協定的差別就不展開了。采用這種作用域的對象,生命周期限定在

WebSocket

範圍内,其實它和

request

作用域挺像的,都是站在通信協定的角度看

Spring

對象生命周期的。

SimpleThreadScope

Spring

内部其實還提供有一種單線程作用域,但是這種作用域預設是沒有注冊到

Spring

容器中的,

Spring

隻是提供了這種作用域的實作類。

如果想要使用,需要手動注冊這種作用域:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd">

    <bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
        <property name="scopes">
            <map>
                <entry key="thread">
                    <bean class="org.springframework.context.support.SimpleThreadScope"/>
                </entry>
            </map>
        </property>
    </bean>

    <bean id="thing2" class="x.y.Thing2" scope="thread">
        <property name="name" value="Rick"/>
        <aop:scoped-proxy/>
    </bean>

    <bean id="thing1" class="x.y.Thing1">
        <property name="thing2" ref="thing2"/>
    </bean>

</beans>