6.5.5 自定义 (custom) 作用域
Bean 的作用域是可扩展的; 您可以定义自己的作用域, 甚至重新定义现有作用域, 尽管后者被认为是不好的做法, 您无法覆盖内置的单例和原型作用域.
创建自定义作用域
要将自定义作用域集成到 Spring 容器中, 需要实现 org.springframework.beans.factory.config.Scope 接口, 本节将对此进行介绍. 有关如何实现自己的作用域的方法, 请参阅 Spring 框架本身的 Scope 实现以及 javadocs 提供的 Scope 实现, 它们阐述了您需要的更详细地实现方法.
Scope 接口有四种方法, 可以从作用域中获取对象, 从作用域中删除它们, 并允许它们被销毁.
以下方法从相关的作用域返回对象. 例如, 会话作用域的实现会返回会话作用域的 bean(如果它不存在, 在将其绑定到会话上以供将来参考之后, 该方法会返回该 bean 的新实例).
Object get(String name, ObjectFactory objectFactory)
以下方法从相关的作用域中删除对象. 例如, 会话作用域的实现从相关的会话中删除会话作用域的 bean. 应被返回的对象, 但如果找不到具有指定名称的对象, 则可以返回 null.
Object remove(String name)
以下方法注册了回调函数, 在作用域被销毁时或者当作用域中的特定对象被销毁时, 该函数会被执行. 有关销毁回调的更多信息, 请参阅 javadocs 或 Spring 作用域实现.
void registerDestructionCallback(String name, Runnable destructionCallback)
以下方法获取相关作用域的对话标识符. 对于每个作用域, 标识符都不同. 对于会话作用域的实现, 该标识符可以是会话标识符.
String getConversationId()
使用自定义作用域
在编写并测试一个或多个自定义 Scope 实现之后, 您需要让 Spring 容器理解您的新作用域. 以下方法是使用 Spring 容器注册新 Scope 的核心方法:
void registerScope(String scopeName, Scope scope);
此方法在 ConfigurableBeanFactory 接口上声明, 对于通过 BeanFactory 属性装载到 Spring 上的该接口的大多数具体 ApplicationContext 实现是可用的.
registerScope(..)方法的第一个参数是与作用域相关联的唯一名称; Spring 容器本身的这些名称的例子有 singleton 和 prototype. registerScope(..)方法的第二个参数是您希望注册和使用的自定义 Scope 实现的实际实例.
假设您编写了自定义 Scope 实现, 然后按如下所示进行注册.
注意: 下面的示例使用 Spring 附带的 SimpleThreadScope, 但默认情况下未注册. 对于您自己的自定义 Scope 实现, 这些指令是相同的.
- Scope threadScope = new SimpleThreadScope();
- beanFactory.registerScope("thread", threadScope);
然后创建符合自定义作用域的作用域规则的 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>
注意: 当您在 FactoryBean 实现中放置 < aop:scoped-proxy />时, 它是作用域的工厂 bean 本身, 而不是从 getObject()返回的对象.
来源: http://www.bubuko.com/infodetail-2945842.html