将请求范围的 bean 自动装配到应用程序范围的 bean 中
Posted
技术标签:
【中文标题】将请求范围的 bean 自动装配到应用程序范围的 bean 中【英文标题】:Autowiring request scoped beans into application scoped beans 【发布时间】:2012-11-13 09:49:57 【问题描述】:是否可以。即
我有一个类 RequestScopedBean:
class RequestScopedBean
....
....
....
还有一个类应用程序范围的 bean,其中请求范围的 bean 是自动装配的。
class ApplicationScopedBean
@Autowire
private RequestScopedBean requestScopedBean;
....
....
....
spring-config xml如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd
">
<bean id="applicationScopedBeans" class="ApplicationScopedBean" />
<bean id="requestScopedBean" class="RequestScopedBean" scope="request">
</bean>
</beans>
当我尝试运行此应用程序时,applicationScopedBean 的 bean 创建失败并出现以下错误:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'ApplicationScopedBean': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private RequestScopedBean requestScopedBean; nested exception is java.lang.IllegalStateException: No Scope registered for scope 'request'
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:288)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1074)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:312)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:192)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1075)
at com.amazon.coral.reflect.instantiate.SpringInstantiatorFactory$1.newInstance(SpringInstantiatorFactory.java:168)
... 19 more
【问题讨论】:
【参考方案1】:@Airwavezx 等价的注解如下:
@Scope( value = SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS )
【讨论】:
【参考方案2】:上述异常表明您没有正确配置 Spring 以提供请求范围的 bean。
您需要按照文档here 中的说明将其添加到您的 web.xml:
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
但是,您的问题不仅仅是配置。您正在尝试将请求范围的 bean 注入单例范围的 bean。 Spring 在 DI 容器启动时解决依赖关系并实例化单例。这意味着 ApplicationScopedBean 只会被创建一次(此时不会有任何请求在运行,因此自动装配很可能会失败)。
如果您使用的是原型作用域 bean 而不是请求作用域,则您必须考虑一种方法,在每次使用时为单例作用域 bean 提供一个新实例。 Spring 文档的Method Injection 章节中描述了此方法。
【讨论】:
【参考方案3】:您还必须将 requestScopedBean
标记为范围代理,这样 Spring 将注入 requestScopedBean 的代理并在后台适当地管理范围。
<bean id="requestScopedBean" class="RequestScopedBean" scope="request">
<aop:scoped-proxy/>
</bean>
更多here
【讨论】:
什么是 @Annotation 等价物?以上是关于将请求范围的 bean 自动装配到应用程序范围的 bean 中的主要内容,如果未能解决你的问题,请参考以下文章
在 Spring Boot 中配置 RequestContextListener
Hibernate Envers 禁用 RevisionListener