我们都知道,Spring 只支持两种默认的 Scope:
- singleton:在单例作用域中,从 Spring 容器中获取的每个 bean 都是同一个对象。
- prototype:在原型作用域中,从 Spring 容器中获取的每个 bean 都是不同的对象。
Spring Web 扩展了 Scope 并添加了:
- RequestScope:在同一个请求中,从 Spring 容器中获取的 bean 都是同一个对象。
- SessionScope:在同一个会话中,从 Spring 容器中获取的 bean 都是同一个对象。
即便如此,有些场景仍然无法满足我们的要求。
例如,如果我们希望在同一个线程中从 Spring 容器中获取的所有 bean 都是同一个对象,该怎么办呢?
这就需要自定义 Scope。
第一步,实现 Scope 接口:
public class ThreadLocalScope implements Scope {
privatestaticfinal ThreadLocal THREAD_LOCAL_SCOPE = new ThreadLocal();
@Override
public Object get(String name, ObjectFactory<?> objectFactory) {
Object value = THREAD_LOCAL_SCOPE.get();
if (value!= null) {
return value;
}
Object object = objectFactory.getObject();
THREAD_LOCAL_SCOPE.set(object);
return object;
}
@Override
public Object remove(String name) {
THREAD_LOCAL_SCOPE.remove();
returnnull;
}
@Override
public void registerDestructionCallback(String name, Runnable callback) {
}
@Override
public Object resolveContextualObject(String key) {
returnnull;
}
@Override
public String getConversationId() {
returnnull;
}
}第二步,将新定义的“Scope”注入到 Spring 容器中:
@Component
public class ThreadLocalBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
beanFactory.registerScope("threadLocalScope", new ThreadLocalScope());
}
}
第三步,使用新定义的“Scope”:
@Scope("threadLocalScope")
@Service
public class CService {
public void add() {
}
}