一般都知道spring2.x bean的作用域
Bean作用域
作用域 | 描述 |
---|---|
singleton | 在每个Spring IoC容器中一个bean定义对应一个对象实例。 |
prototype | 一个bean定义对应多个对象实例。 |
request | 在一次HTTP请求中,一个bean定义对应一个实例;即每次HTTP请求将会有各自的bean实例,它们依据某个bean定义创建而成。该作用域仅在基于web的Spring |
session | 在一个HTTP |
global session | 在一个全局的HTTP |
看完官网文档明白了,spring2.xbean的作用域可以自定义作用域,甚至重新定义现有的作用域(不提倡这么做,而且你不能覆盖内置的singleton
和prototype
作用域)。
spring bean 自定义作用域
作用域由接口org.springframework.beans.factory.config.Scope
定义。
要将你自己的自定义作用域集成到Spring容器中,需要实现该接口。它本身非常简单,只有两个方法,分别用于底层存储机制获取和删除对象。自定义作用域可能超出了本参考手册的讨论范围,但你可以参考一下Spring提供的Scope
实现,以便于去如何着手编写自己的Scope实现。
在实现一个或多个自定义Scope
并测试通过之后,接下来就是如何让Spring容器识别你的新作用域。ConfigurableBeanFactory
接口声明了给Spring容器注册新Scope
的主要方法。(大部分随Spring一起发布的BeanFactory
具体实现类都实现了该接口);
该接口的主要方法如下所示:
package org.springframework.beans.factory.config;
import org.springframework.beans.factory.ObjectFactory;
public interface Scope
{
public abstract Object get(String s, ObjectFactory objectfactory);
public abstract Object remove(String s);
public abstract void registerDestructionCallback(String s, Runnable runnable);
public abstract String getConversationId();
}
1.实现 Scope 接口
package com.myscope;
import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.ObjectFactory;
public class ThreadScope implements org.springframework.beans.factory.config.Scope{
private final ThreadLocal<Object> threadScope = new ThreadLocal<Object>() {
protected Object initialValue() {
return new HashMap<String, Object>();
}
};
public Object get(String s, ObjectFactory objectfactory) throws BeansException{
Map<String, Object> scope = (Map<String, Object>) threadScope.get();
Object object = scope.get(s);
if (object == null) {
object = objectfactory.getObject();
scope.put(s, object);
}
return object;
}
public Object remove(String name) {
Map<String, Object> scope = (Map<String, Object>) threadScope.get();
return scope.remove(name);
}
public String getConversationId() {
return null;
}
public Object resolveContextualObject(String key) {
return null;
}
public void registerDestructionCallback(String name, Runnable callback) {
}
}
2.通过工厂注册
applicationContext.getBeanFactory().registerScope("myScope", scope);
然后你就可以像下面这样创建与自定义Scope
的作用域规则相吻合的bean定义了:
<bean id="..." class="..." scope="myScope"/>
完整xml配置:
<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer"> <property name="scopes"> <map> <entry key="thread" value="com.myscope.ThreadScope"/> </map> </property> </bean> <bean id="bar" class="com.demo1" scope="thread"> <property name="name" value="Rick"/> <aop:scoped-proxy/> </bean>
或者:
<bean id="myScope" class="com.myscope.ThreadScope"/> <bean id="customerScope" class="org.springframework.beans.factory.config.CustomScopeConfigurer"> <property name="scopes"> <map> <entry key="myScope"> <bean class="myScope"/> </entry> </map> </property> </bean> <bean id="usesScope" class="com.demo" scope="myScope"/>