请求作用域 bean 的实例化

instanciation of a request scoped bean

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

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

@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 方法,在其中实例化任何 class(不一定是 spring 托管 bean),设置所需的参数和 return 实例。这种情况下的范围可以在方法级别提供。像这样:

@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注解class。

  1. 如上所示在 RequestScopedBean 中添加 @Scope 注释,并从配置中删除 RequestScopeBean 的 @Bean 方法 class。