我有一个控制器,希望每个会话都是唯一的。根据Spring文档,有两个实现细节:
1. 初始Web配置
为了支持在请求、会话和全局会话级别上对bean进行范围限制(Web Scoped Beans),在定义bean之前需要进行一些微小的初始配置。
我已经按照文档中的说明将以下内容添加到我的web.xml
中:
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
2. 作为依赖项的作用域限定 Bean
如果您想将(例如)一个 HTTP 请求作用域的 Bean 注入到另一个 Bean 中,必须在作用域 Bean 的位置注入 AOP 代理。
我已经使用 @Scope
注释了该 Bean,并提供了以下的 proxyMode
:
@Controller
@Scope(value="session", proxyMode=ScopedProxyMode.TARGET_CLASS)
public class ReportBuilder implements Serializable {
...
...
}
问题
尽管我进行了上述配置,但我收到以下异常:
org.springframework.beans.factory.BeanCreationException: 创建bean时出错,bean名称为'scopedTarget.reportBuilder':当前线程未激活范围“session”;如果您打算从单例中引用它,请考虑定义一个作用域代理bean;嵌套异常是java.lang.IllegalStateException:未找到绑定请求的线程:您是否在实际网络请求之外引用请求属性或处理原始接收线程之外的请求?如果您确实在网络请求内操作并仍然收到此消息,则您的代码可能正在DispatcherServlet / DispatcherPortlet之外运行:在这种情况下,请使用RequestContextListener或RequestContextFilter公开当前请求。
更新1
以下是我的组件扫描。 我在 web.xml
中有以下内容:
<context-param>
<param-name>contextClass</param-name>
<param-value>
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>org.example.AppConfig</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
接下来是 AppConfig.java
的内容:
@Configuration
@EnableAsync
@EnableCaching
@ComponentScan("org.example")
@ImportResource("classpath:applicationContext.xml")
public class AppConfig implements AsyncConfigurer {
...
...
}
更新 2
我已经创建了一个可重现的测试案例。这是一个较小的项目,因此存在一些差异,但是发生了相同的错误。由于有相当多的文件,因此我已将其上传为 tar.gz
文件到megafileupload。