Spring 2.0 在 singleton、prototype 之外新增 request、session、globalSession 三種 Web Scope。本文從源碼角度解析 Scope 介面、ConfigurableBeanFactory 註冊機制、WebApplicationContext 初始化流程,揭示為何僅 Web 容器可用。
public interface Scope {
Object get(String name, ObjectFactory objectFactory); // 取得或建立 Bean
Object remove(String name); // 移除 Bean
}
public interface ConfigurableBeanFactory extends HierarchicalBeanFactory {
void registerScope(String scopeName, Scope scope); // 註冊新 Scope
void destroyScopedBean(String beanName); // 銷毀 Scope Bean
}
String scopeName = mergedBeanDefinition.getScope(); // 讀取 bean 定義中的 scope
Scope scope = (Scope) this.scopes.get(scopeName); // 從工廠取得 Scope 實現
if (scope == null) throw new IllegalStateException(...);
Object scopedInstance = scope.get(beanName, new ObjectFactory() {
public Object getObject() {
beforePrototypeCreation(beanName);
try { return createBean(beanName, mergedBeanDefinition, args); }
finally { afterPrototypeCreation(beanName); }
}
});
public interface WebApplicationContext extends ApplicationContext {
String SCOPE_REQUEST = "request";
String SCOPE_SESSION = "session";
String SCOPE_GLOBAL_SESSION = "globalSession";
}
// 所有 WebApplicationContext 實現類在 postProcessBeanFactory 中註冊
protected void postProcessBeanFactory(ConfigurableListableBeanFactory bf) {
bf.registerScope(SCOPE_REQUEST, new RequestScope());
bf.registerScope(SCOPE_SESSION, new SessionScope(false));
bf.registerScope(SCOPE_GLOBAL_SESSION, new SessionScope(true));
}
BeanFactory 僅內建 singleton/prototype,**不含 Web Scope 實現**。WebApplicationContext(及其子類)在啟動時自動註冊三個 Web Scope。scope="request" 會拋出 No Scope registered 異常。Scope 介面並註冊,打造自定義生命週期(如 Thread Scope、Tenant Scope)。