2

Spring 中的请求范围 bean 意味着容器为每个 HTTP 请求创建一个 bean 实例。

假设我有一个 RequestScopedBean bean:

@Component
public class RequestScopedBean {
  @PostConstruct
  void init() {
     System.out.println("Init method called for each incoming HTTP Request");
  }
}

public void doSomething() {}

配置 :

@Configuration
public class MyBeansConfig {
  @Bean
  @Scope(value="request", proxyMode=TARGET_CLASS)
  public RequestScopedBean requestScopedBean() {
     return new requestScopedBean();
  }         
}

我在 Singleton bean 中使用我的RequestScopedBean -期望为每个传入的 HTTP 请求调用 init() 方法。但事实并非如此。init() 方法只被调用一次,这意味着容器只创建我的RequestScopedBean的一个实例!!!有人可以向我解释一下:如果我期望的行为是正确的/或者配置有什么问题。

4

1 回答 1

3

您已经为 RequestScopedBean 完成了冗余配置。对于 Spring 托管 bean(如 @Component),您无需在 Configuration 类中使用 @Bean 定义相同的内容。您可以只使用 @Component 注释类,spring 会为您扫描它并在需要时实例化它。并且它的范围可以在类级别上提供。像这样:

@Component
@Scope(value="request", proxyMode=ScopedProxyMode.TARGET_CLASS)
public class RequestScopedBean {
 @PostConstruct
 void init() {
  System.out.println("Init method called for each incoming HTTP Request");

}

否则,您可以定义一个 @Bean 方法,在其中实例化任何类(不一定是 spring 托管 bean),设置所需的参数并返回实例。在这种情况下,可以在方法级别提供范围。像这样:

@Configuration
public class MyBeansConfig {
  @Bean
  @Scope(value="request", proxyMode=ScopedProxyMode.TARGET_CLASS)
  public RequestScopedBean requestScopedBean() {
    //if needed set the required parameters
     return new RequestScopedBean();
  }         
}

在你的情况下,你已经做了两个,这不是必需的,可能这就是它没有按预期运行的原因。要解决您的问题,请执行以下任一操作,

  1. 删除 RequestScopedBean 类中的 @Component 注释。

或者

  1. 如上所示在 RequestScopedBean 中添加 @Scope 注释并从 Configuration 类中删除 RequestScopeBean 的 @Bean 方法。
于 2016-09-14T14:23:25.770 回答