Spring擴展(2)-Spring Scope總結(jié)

0.先醒醒腦

WechatIMG2220.jpeg

1.關(guān)于scope

  • singleton:在spring容器中只存在一個實例,所有對該對象的引用將共享這個實例,該實例從容器啟動,并因為第一次被請求而初始化之后,將一直存活到容器退出;
  • prototype:容器在接受到該類型對象的請求時,會每次都重新生成一個新的對象實例給請求方,該對象的實例化以及屬性設(shè)置等工作都是由容器負責的,但是只要準備完畢,并且對象實例返回給請求方的時候,容器就不再擁有當前返回對象的引用,請求方需要自己負責當前返回對象的生命周期管理工作,包括容器的摧毀;
  • request:XmlWebApplicationContext會為每個HTTP請求創(chuàng)建一個全新的RequestProcessor對象供當前請求使用,當請求結(jié)束后,該對象實例的生命周期即告結(jié)束;從不是很嚴格的意義上說,request可以看作prototype的一種特例,除了場景更加具體 之外,語意上差不多;
  • session:request相比,除了擁有session scope的bean的實例具有比request scope的bean可能更長的存活時間,其他方面真是沒什么差別。
  • global session:沒啥好說的;

2.自定義scope

要實現(xiàn)自己的scope,可以參照RequestScope和SessionScope,首先必須實現(xiàn)Scope接口或者繼承AbstractRequestAttributesScope,接口定義中的4個方法并非都是必須的,但get和remove方法必須實現(xiàn);

1.有了Scope的實現(xiàn)類之后,我們需要把這個Scope注冊到容器中,才能供相應(yīng)的bean定義使用。使用編碼注冊的方式是通過ConfigurableBeanFactory#registerScope注冊自定義scope;

  Scope customScope = new CustomScope(); 
  beanFactory.registerScope("custom",customScope);

正常情況下都是按如下方式注冊:

    ClassPathXmlApplicationContext context = ...;
    context.getBeanFactory().registerScope("custom", new CustomScope());

2.使用xml的方式注入:

<bean id="custom" class="CustomScope"/>
<bean id="customerScope" class="org.springframework.beans.factory.config.CustomScopeConfigurer">
    <property name="scopes">
        <map>
            <entry key="custom">
                <bean class="custom"/>
            </entry>
        </map>
    </property>
</bean>
<bean id="usesScope" class="org.springframework.beans.TestBean" scope="custom"/>

原因是這樣:
CustomScopeConfigurer 實現(xiàn)了BeanFactoryPostProcessor,BeanClassLoaderAware等接口,SpringIoC容器允許BeanFactoryPostProcessor在容器實例化任何bean之前讀取bean的定義(配置元數(shù)據(jù)),并可以修改它。而CustomScopeConfigurer中實現(xiàn)的postProcessBeanFactory方法;

public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        if (this.scopes != null) {
            Iterator var2 = this.scopes.entrySet().iterator();

            while(var2.hasNext()) {
                Entry<String, Object> entry = (Entry)var2.next();
                String scopeKey = (String)entry.getKey();
                Object value = entry.getValue();
                if (value instanceof Scope) {
                    beanFactory.registerScope(scopeKey, (Scope)value);
                } else {
                    Class scopeClass;
                    if (value instanceof Class) {
                        scopeClass = (Class)value;
                        Assert.isAssignable(Scope.class, scopeClass, "Invalid scope class");
                        beanFactory.registerScope(scopeKey, (Scope)BeanUtils.instantiateClass(scopeClass));
                    } else {
                        if (!(value instanceof String)) {
                            throw new IllegalArgumentException("Mapped value [" + value + "] for scope key [" + scopeKey + "] is not an instance of required type [" + Scope.class.getName() + "] or a corresponding Class or String value indicating a Scope implementation");
                        }

                        scopeClass = ClassUtils.resolveClassName((String)value, this.beanClassLoader);
                        Assert.isAssignable(Scope.class, scopeClass, "Invalid scope class");
                        beanFactory.registerScope(scopeKey, (Scope)BeanUtils.instantiateClass(scopeClass));
                    }
                }
            }
        }

    }

它同樣會去掃描加載的配置文件中的scope,并進行注冊;

補充:關(guān)于BeanFactoryPostProcessor的內(nèi)容,Spring IoC容器允許同時可以定義多個BeanFactoryPostProcessor,通過實現(xiàn)order接口來確定各個BeanFactoryPostProcessor執(zhí)行順序。注冊一個BeanFactoryPostProcessor實例需要定義一個Java類來實現(xiàn)BeanFactoryPostProcessor接口,并重寫該接口的postProcessorBeanFactory方法。通過beanFactory可以獲取bean的定義信息,并可以修改bean的定義信息。

public interface BeanFactoryPostProcessor {
    void postProcessBeanFactory(ConfigurableListableBeanFactory var1) throws BeansException;
}

在Spring中內(nèi)置了一些BeanFactoryPostProcessor實現(xiàn)類,可遵循如下關(guān)系延伸閱讀;


1071792-20170320144908611-422885334.jpg

關(guān)于在spring-boot中自定義scope其實也類似,改天再將案例貼出!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容