Spring(10)——bean作用范围(二)——自定义scope
来源:互联网 发布:ubuntu安装桌面环境 编辑:程序博客网 时间:2024/06/05 01:07
10.7 自定义Scope
如果用户觉得Spring内置的几种Scope不能满足需求,则可以定制自己的Scope,即实现自己的org.springframework.beans.factory.config.Scope
。Scope接口定义了如下几个方法,详情请参看Spring的API文档。
public interface Scope {Object get(String name, ObjectFactory<?> objectFactory);Object remove(String name);void registerDestructionCallback(String name, Runnable callback);Object resolveContextualObject(String key);String getConversationId();}
下面来看一下Spring内部Scope为application的定义,即ServletContextScope
的定义。
public class ServletContextScope implements Scope, DisposableBean {private final ServletContext servletContext;private final Map<String, Runnable> destructionCallbacks = new LinkedHashMap<String, Runnable>();/** * Create a new Scope wrapper for the given ServletContext. * @param servletContext the ServletContext to wrap */public ServletContextScope(ServletContext servletContext) {Assert.notNull(servletContext, "ServletContext must not be null");this.servletContext = servletContext;}@Overridepublic Object get(String name, ObjectFactory<?> objectFactory) {Object scopedObject = this.servletContext.getAttribute(name);if (scopedObject == null) {scopedObject = objectFactory.getObject();this.servletContext.setAttribute(name, scopedObject);}return scopedObject;}@Overridepublic Object remove(String name) {Object scopedObject = this.servletContext.getAttribute(name);if (scopedObject != null) {this.servletContext.removeAttribute(name);this.destructionCallbacks.remove(name);return scopedObject;}else {return null;}}@Overridepublic void registerDestructionCallback(String name, Runnable callback) {this.destructionCallbacks.put(name, callback);}@Overridepublic Object resolveContextualObject(String key) {return null;}@Overridepublic String getConversationId() {return null;}/** * Invoke all registered destruction callbacks. * To be called on ServletContext shutdown. * @see org.springframework.web.context.ContextCleanupListener */@Overridepublic void destroy() {for (Runnable runnable : this.destructionCallbacks.values()) {runnable.run();}this.destructionCallbacks.clear();}}
10.7.1注册
自定义了Scope之后我们得在Spring中进行注册,好让Spring能够对其进行识别,这样我们才能在进行对应bean定义的时候使用自定义的Scope。自定义Scope的注册有两种方式,一种是程序化的,一种是通过XML进行配置的。
我们先来实现一个自定义的Scope供注册自定义Scope使用。
public class MyScope implements Scope {private Map<String, Object> beanMap = new ConcurrentHashMap<String, Object>();/** * 获取指定beanName的bean实例 * @param name 对应bean的beanName * @param objectFactory 可以产生对应bean实例的ObjectFactory * @return 获取到的实例 */public Object get(String name, ObjectFactory<?> objectFactory) {System.out.println("------------get-----------" + name);synchronized (this) {if (!beanMap.containsKey(name)) {System.out.println("-----------not--exists-------" + name);beanMap.put(name, objectFactory.getObject());}}return beanMap.get(name);}/** * 底层移除name对应的对象。实现者需要同时移除注册的销毁化回调方法 * @param name * @return 移除的对象 */public Object remove(String name) {return beanMap.remove(name);}/** * 注册一个销毁时的回调方法 * @param name * @param callback */public void registerDestructionCallback(String name, Runnable callback) {}public Object resolveContextualObject(String key) {return null;}public String getConversationId() {return null;}}
程序化注册自定义Scope是通过ConfigurableBeanFactory的registerScope()方法进行的,其对应定义如下,scopeName表示我们需要注册的scope的名称,第二个参数Scope表示我们需要注册的Scope的一个实例。
/** * Register the given scope, backed by the given Scope implementation. * @param scopeName the scope identifier * @param scope the backing Scope implementation */void registerScope(String scopeName, Scope scope);
我们可以通过常用的ApplicationContext,如ClassPathXmlApplicationContext等的getBeanFactory()方法就能获取到对应的ConfigurableBeanFactory对象,然后进行注册。如:
ClassPathXmlApplicationContext context = ...;context.getBeanFactory().registerScope("myScope", new MyScope());
通过XML配置进行注册是指通过在Spring的配置文件中定义一个CustomScopeConfigurer类型的bean,并通过其setScopes()方法注入自定义Scope。如下所示,我们通过XML配置注册了一个名叫myScope的Scope定义。
<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer"><property name="scopes"><map><entry key="myScope"><bean class="com.app.MyScope"/></entry></map></property></bean>
之后就可以在定义bean的时候使用我们自己定义的myScope来作为bean定义的Scope了。
<bean id="hello" class="com.app.Hello" scope="myScope"/>
在上述配置中我们指定了id为hello的bean定义的scope为自定义的myScope。之后运行如下测试代码,我们可以看到控制台的输出过程。我们每从bean容器中获取一次hello的实例,对应MyScope的get()方法就会被调用一次。
@org.junit.Testpublic void test() {System.out.println(context.getBean("hello"));System.out.println(context.getBean("hello"));}
(注:本文是基于Spring4.1.0所写)
- Spring(10)——bean作用范围(二)——自定义scope
- Spring(10)——bean作用范围
- bean作用范围(scope)
- Spring bean的作用域(scope)
- Maven开发笔记(一)—— Maven中的依赖作用范围(scope)
- Spring中bean的作用范围:Scope属性的值
- Spring注入非单例bean以及scope的作用范围
- Spring注入非单例bean以及scope的作用范围
- spring注入非单例bean及scope的作用范围
- Spring——自定义属性编辑器+Bean的生存范围+Bean的生命周期
- Spring scope bean生存范围
- Spring中Bean的作用域(Scope)
- spring——bean的生存范围
- Spring基础—装配bean(二)
- Spring基础—装配bean(二)
- Spring基础—装配bean(二)
- Spring学习笔记——Spring Scope(作用域)详解
- Spring——bean标签的scope属性
- plsql developer 12 32位 v12.0.1汉化中文版
- HDU 5920Ugly Problem
- SSM整合表单接受--第二天
- 神奇的fans oj40
- linux-1 查看文件类型及统计文件容量信息
- Spring(10)——bean作用范围(二)——自定义scope
- (OOP:Object Oriented Programming)面向对象
- 斐波纳契数列 oj39
- android byteBuffer的使用
- Eclipse很卡的解决方法
- Swift 资源库
- 题目:poj – 2395 (B题)
- 手工方式实现Spring工厂创建对象
- SlickEdit Pro(文本编辑器) v20.0.0.12 免费版