3.5.5 自定义作用域

bean作用域机制是可扩展的; 你可以定义自己的作用域,甚至重新定义现有的作用域,虽然后者被认为是不推荐的做法,并且,你不能覆盖内置的singletonprototype作用域。

创建自定义作用域

要将自定义作用域集成到Spring容器中,您需要实现本部分中描述的org.springframework.beans.factory.config.Scope接口。 有关如何实现自己的作用域的想法,请参阅Spring框架本身和Scope javadocs,它解释了您需要更详细实现的方法。

Scope接口有四种方法来从作用域中获取对象,将它们从作用域中删除,并允许它们被销毁。

下面的方法作用是返回作用域中对象。比如,session作用域的实现,该方法返回session-scoped会话作用域bean(若不存在,方法创建该bean的实例,并绑定到session会话中,用于引用,然后返回该对象)

Object get(String name, ObjectFactory objectFactory)

下面的方法作用是从作用域中删除对象。以session作用域实现为例,方法内删除对象后,会返回该对象,但是若找不到指定对象,则会返回null

Object remove(String name)

下面的方法作用是注册销毁回调函数,销毁是指对象销毁或者是作用域内对象销毁。销毁回调的详情请参看javadocs或者Spring 作用域实现。

void registerDestructionCallback(String name, Runnable destructionCallback)

下面的方法,用于获取作用域会话标识。每个作用域的标识都不一样。比如,session作用域的实现中,标识就是session标识(应该是指sessionId)

String getConversationId()

使用自定义作用域

在你编写和测试一个或多个自定义Scope实现之后,你需要让Spring容器意识到你的新作用域。 下面的方法是使用Spring容器注册一个新的Scope的核心方法:

void registerScope(String scopeName, Scope scope);

这个方法在ConfigurableBeanFactory接口上声明,在大多数具体的ApplicationContext实现中都可以使用,它通过BeanFactory属性与Spring一起提供。

registerScope(..)方法的第一个参数是与作用域相关联的唯一名称; Spring容器本身中这样的名称的例子是singletonprototyperegisterScope(..)方法的第二个参数是你想要注册和使用的自定义Scope实现的一个实际实例。

假设你编写了你的自定义Scope实现,然后像下面那样注册它。

[Note]
下面的示例使用Spring Simple中包含的SimpleThreadScope,但默认情况下未注册。 这些指令对于您自己的自定义Scope实现是一样的。
Scope threadScope = new SimpleThreadScope();
beanFactory.registerScope("thread", threadScope);

然后,创建符合您的自定义Scope的作用域规则的bean定义:

<bean id="..." class="..." scope="thread">

使用自定义Scope 实现,你不限于作用域的编程(即代码)注册。 你也可以使用CustomScopeConfigurer类来声明性地注册Scope

<?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
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        http://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="bar" class="x.y.Bar" scope="thread">
        <property name="name" value="Rick"/>
        <aop:scoped-proxy/>
    </bean>

    <bean id="foo" class="x.y.Foo">
        <property name="bar" ref="bar"/>
    </bean>

</beans>
[Note]
当你在FactoryBean实现中放置 <aop:scoped-proxy/>时,它是工厂bean本身的作用域,而不是从 getObject()返回的对象。

results matching ""

    No results matching ""