请求作用域 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();
}
}
在你的情况下,你已经完成了这两项操作,这不是必需的,可能这就是为什么它没有按预期运行的原因。要解决您的问题,请执行以下任一操作,
- 移除RequestScopedBean中的@Component注解class。
或
- 如上所示在 RequestScopedBean 中添加 @Scope 注释,并从配置中删除 RequestScopeBean 的 @Bean 方法 class。
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();
}
}
在你的情况下,你已经完成了这两项操作,这不是必需的,可能这就是为什么它没有按预期运行的原因。要解决您的问题,请执行以下任一操作,
- 移除RequestScopedBean中的@Component注解class。
或
- 如上所示在 RequestScopedBean 中添加 @Scope 注释,并从配置中删除 RequestScopeBean 的 @Bean 方法 class。