0

我有一个弹簧 MVC 应用程序。我有一个作为单例连接的 bean,还有一个也是自动连接但属于请求范围的字段。例如:

class Hello {

  @Autowired
  BDepend b; // this is defined as a request scope bean

  @Autowired
  public Hello(ADepend a){
  }
}

这里我的类 Hello 是一个单例,但 BDepend 是一个请求范围对象。由于 Hello 是单例,spring 如何为每个请求处理 Bdepend 的正确实例。

4

1 回答 1

1

默认情况下,您将在应用程序启动时出现运行时异常。像这样的东西:

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 具有不同的范围。

于 2013-07-23T15:55:42.073 回答