我有一个spring MVC应用程序。我有一个连接为单例的bean,也是一个自动连接但是请求范围的字段。 例如:
class Hello {
@Autowired
BDepend b; // this is defined as a request scope bean
@Autowired
public Hello(ADepend a){
}
}
这里我的类Hello是单例,但BDepend是请求范围对象。 Spring是如何为每个请求处理Bdepend的正确实例,因为Hello是一个单例。
答案 0 :(得分:1)
默认情况下,应用程序sturtup会出现运行时异常。像这样:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'b': Scope 'request' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton;
要在某些单例中使用请求范围对象,您需要每次从应用程序上下文获取一个新的实例。你可以这样做:
直接使用应用程序上下文
class Hello {
@Autowired
private ApplicationContext ctx;
@Autowired
public Hello(ADepend a){
}
public useB(){
BDepend instance = ctx.getBean(BDepend.class);
instance.doSomething();
}
}
或通过javax.inject.Provider
获取新的实例。
class Hello {
@Autowired
private Provider<BDepend> provider;
@Autowired
public Hello(ADepend a){
}
public useB(){
BDepend instance = this.provider.get();
instance.doSomething();
}
}
或为此bean声明范围代理:
@Component
@Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)
class BDepend {
}
class Hello {
@Autowired
private BDepend b;
@Autowired
public Hello(ADepend a){
}
public useB(){
b.doSomething();
}
}
或使用系统范围的范围代理
<context:component-scan base-package="com.mycompany.beans" scoped-proxy="targetClass" />
我个人更喜欢第二个选项(javax.inject.Provider
):从代码中可以清楚地看出你的bean有不同的范围。