当前位置: 首页 > 面试题库 >

在多线程Web应用程序中访问请求范围的Bean

荀子轩
2023-03-14
问题内容

场景:我们有一个在Websphere中运行的Spring托管的Web应用程序。(Spring 3.0.x,WAS
7)Webapp通过Spring的Web应用程序利用Websphere的工作管理器WorkManagerTaskExecutor(配置为10的线程池)以执行计算密集型db读取操作。因此,基本上,有一个请求来生成10个不同的文件。要生成文档,只需db读取即可收集/处理数据。因此,我们基本上产生了10个线程来处理10个文档,最后收集了10个工作人员返回的10个文档,并将它们合并并写回给客户端一个很大的响应。我们确定的是,当10个线程正在收集/处理数据时,会进行许多类似的数据库调用。因此,我们想到的是围绕最执行的db方法创建一个Aspect以缓存响应。该方面被配置为单例,并且该方面使用的缓存被自动连接到该方面,并且将范围设置为request-
scope,以便每个请求都有自己的缓存。

问题:现在,这种方法的问题在于,当线程正在执行其数据库调用并且Aspect被插入时,我们将获得java.lang.IllegalStateException: No thread-bound request found异常。我理解这是完全有效的,因为线程是在请求上下文之外执行的。

有没有办法解决这个问题?是否可以将具有请求范围的缓存的方面应用于这些线程调用的方法?


问题答案:

我认为您无法直接执行此操作。即使可以,这也会有些丑陋。但是,您可以生成唯一的请求标识符(甚至-
使用会话ID,但要小心使用多个选项卡),并将其传递给每个处理线程。然后,方面可以使用该ID作为缓存的键。缓存本身也将是单例,但将存在Map<String, X>,其中StringID是ID,X是您的缓存结果。

为了使事情更容易处理,您可以使用@Async方法(而不是手动生成线程),并且每个@Async方法都可以将缓存ID作为其第一个参数传递。

(当然,您的异步方法应该返回,Future<Result>以便您可以在请求线程中收集其结果)



 类似资料:
  • 问题内容: 自两年以来,我一直在使用java(Servlets,JSPs)进行Web应用程序开发。在那两年中,我从不需要在任何项目中使用(明确地- 众所周知,servlet容器使用线程为不同的请求提供相同的servlet)。 但是,每当我参加Web开发人员职位(java)的面试时,就会有几个与java中的线程相关的问题。我知道Java线程的基础知识,因此回答问题不是问题。但是有时我会感到困惑,是否

  • 在SpringBatch 3.0中,我试图在分区和多线程步骤(配置了一个任务:executor bean)中为bean使用新的作业范围功能,在这两种情况下,我都遇到了异常 但如果我使豆步范围它的工作正常。 我注意到JobSynsynizationManager上的评论说 N、 B.每个{@link Job}实现都有责任确保{@link JobContext}在作业执行中可能涉及的每个线程上可用,包

  • 根据文档,scoped bean在每个 容器中只实例化一次。例如,我有一个单例作用域的<code>UserDetails<code>bean,它包含有关用户的信息<br> 在我的main()方法中: 输出将是 因为userDetails是一个单独的bean,所以< code>ud2的第二次检索将给出与ud1相同的结果。 现在这是我的问题: 对于我的Web应用程序,我在我的中有以下bean 第一个问

  • 问题内容: 是否在同一Web应用程序的实例之间共享Java静态变量? 如果Web应用程序使用 MyClass 并且该应用程序的多个实例在Web服务器上运行, myStaticObject 是否被 多次 初始化? 问题答案: 通常,是的。大多数容器将为每个Web应用程序提供单独的类加载器。当多个应用程序使用该类时,这将导致该类被多次加载,从而导致该静态变量的多个实例。 陈述Java语言规范以供参考:

  • 在大容量(每秒约50,000个请求)的java Web应用程序中,我使用Threadloce-app执行一个任务,该任务应按请求范围执行。 我可以使用Spring请求范围实现相同的效果,我想知道哪种性能更好? 在代码中,使用线程本地: 对于每个超文本传输协议请求设置: 使用Spring请求范围: 现在,什么成本更高: 或 不知道有没有人已经尝试过这样的标杆了呢?

  • 基于CGLIB的请求范围bean的堆栈跟踪() 基于JDK-Dynamic-Proxy-Interface的请求范围bean的堆栈跟踪()