请求范围bean的实例化

时间:2016-09-14 09:18:56

标签: spring requestscope

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 的一个实例! 有人可以向我解释:如果我期望的行为是正确的/或配置有什么问题。

1 个答案:

答案 0 :(得分:2)

您已为RequestScopedBean完成了冗余配置。 对于spring托管bean(如@Component),您不需要在带有@Bean的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方法,其中您实例化ANY类(不一定是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注释。
  2. OR

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