从fork-join /线程池调用的Singelton bean中的访问spring请求范围缓存
问题:
启用了Spring且将范围设置为Request的缓存需要由不在请求范围内的singleton bean访问。
解:
Spring使您能够创建缓存,该缓存为请求范围保留数据。 例如
import org.springframework.cache.concurrent.ConcurrentMapCache; import org.springframework.cache.interceptor.SimpleCacheResolver; import org.springframework.cache.support.SimpleCacheManager; import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.ScopedProxyMode; import org.springframework.stereotype.Component; import org.springframework.web.context.WebApplicationContext; import java.util.ArrayList; import java.util.Collection; @Component @Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS) public class RequestScopeCache extends SimpleCacheResolver { public RequestScopeCache() { SimpleCacheManager cacheManager = new SimpleCacheManager(); Collection caches = new ArrayList((Collection) new ConcurrentMapCache( "myCache" , true )); cacheManager.setCaches(caches); cacheManager.initializeCaches(); setCacheManager(cacheManager); } }
您可以在要缓存的任何方法周围使用此缓存
@Cacheable(value = "myCache" , cacheResolver = "requestScopeCache" ) public String getName(String id) { //logic to get name from id }
现在,如果您从具有请求上下文的任何控制器中调用此方法,那就很好了,即,该方法是从服务Web请求的Spring bean的任何其他方法中调用的。
但是,如果您需要从线程池或fork连接池中调用它,事情就会变得棘手。 假设您收到一个请求,并且需要生成多个线程以同时运行以收集数据以将请求存储到服务器。
这些线程耗尽了Web请求线程的上下文,因此在Web请求线程上设置的任何“线程本地”值将对这些线程不可用。
因此,如果最终从这些池线程中调用上述方法(注释为使用缓存),则会从spring中获取异常,例如:
Scope 'session' is not active for the current thread ; IllegalStateException: No ; IllegalStateException: No thread -bound request found
但是有一种简单的方法可以修复它:
- 从Web请求线程获取请求属性
RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
2.将此属性传递给来自pool或fork / join的自定义线程。 基本上可以通过在构造函数中使用此属性创建可运行对象来完成
3.在调用标记为使用请求范围缓存的方法之前,设置请求属性
RequestContextHolder.setRequestAttributes(attributes);
这将在当前线程的本地线程中设置属性,该属性可用于调用上述方法。
测试用例中的综合要求
现在,如果您正在从junit测试方法,则可能根本没有请求对象。
因此,您可以创建一个并按上述方法使用它来填充要测试的属性
RequestContextHolder.setRequestAttributes( new ServletRequestAttributes( new DummyRequest()));
翻译自: https://www.javacodegeeks.com/2020/05/access-spring-request-scope-cache-in-singelton-bean-called-from-fork-join-thread-pool.html
从fork-join /线程池调用的Singelton bean中的访问spring请求范围缓存相关推荐
- fork/join和线程池_从fork-join /线程池调用的Singelton bean中的访问spring请求范围缓存...
fork/join和线程池 问题: 启用了Spring且其范围设置为Request的缓存需要由不在请求范围内的singleton bean访问. 解: Spring使您能够创建缓存,该缓存为请求范围保 ...
- 线程池参数详解_java中常见的六种线程池详解
之前我们介绍了线程池的四种拒绝策略,了解了线程池参数的含义,那么今天我们来聊聊Java 中常见的几种线程池,以及在jdk7 加入的 ForkJoin 新型线程池 首先我们列出Java 中的六种线程池如 ...
- 详解线程池的作用及Java中如何使用线程池
服务端应用程序(如数据库和 Web 服务器)需要处理来自客户端的高并发.耗时较短的请求任务,所以频繁的创建处理这些请求的所需要的线程就是一个非常消耗资源的操作.常规的方法是针对一个新的请求创建一个新线 ...
- python 线程池调用返回结果处理
python多线程调用,如果使用threading.Thread这个如果没有返回值完全没问题,但是有返回的时候就很有问题 下面是一个sample import threading,os,time,da ...
- @async 默认线程池_.NET Web应用中为什么要使用async/await异步编程?
布莱恩特:.NET Core开发精选文章目录,持续更新,欢迎投稿!zhuanlan.zhihu.com 前言 1.什么是async/await? await和async是.NET Framework ...
- python停止线程池_详解python中Threadpool线程池任务终止示例代码
需求 加入我们需要处理一串个位数(0~9),奇数时需要循环打印它:偶数则等待对应时长并完成所有任务:0则是错误,但不需要终止任务,可以自定义一些处理. 关键点 定义func函数处理需求 callbac ...
- python3线程池爬虫_python3多线程爬虫中如何变量?
我们可以把待处理的程序看成一批需要配送的包裹,包裹在不同的货架上摆放.单人整理会比几个人一起摆放要慢的多.同样在计算机处理中,单凭借一个程序打开运行是远远不够用的,我们需要同时处理多个事物,所以多线程 ...
- java fork_浅谈Java的Fork/Join并发框架
前几天有写到整合并发结果的文章,于是联想到了Fork/Join.因为在我看来整合并发结果其实就是Fork/Join中的Join步骤.所以今天我就把自己对Fork/Join一些浅显的理解记录下来. 1. ...
- 浅谈Java的Fork/Join并发框架
1. Fork/Join是什么 Oracle的官方给出的定义是:Fork/Join框架是一个实现了ExecutorService接口的多线程处理器.它可以把一个大的任务划分为若干个小的任务并发执行,充 ...
最新文章
- 参考答案:03 向量空间
- RxSwift之UI控件UIPickerView扩展的使用
- WP8开发札记(一)WP8应用生命周期管理
- JAVA进阶开发之(内部类概述)
- git两个账号切换_Git切换账号方法
- Java笔记-RabbitMQ的消息确认机制(事务)
- matlab 判断元素索引_MATLAB图像处理:08:在交通视频中检测汽车
- 爬虫学习之-Python list 和 str 互转
- free bsd x修改UTC-SCT
- 【2020模拟考试T2】【PAT乙】1032 挖掘机技术哪家强 (20分) 模拟,STL
- Java基础(四) StringBuffer、StringBuilder原理浅析
- VS2017各版本区别
- java操作远端ftp文件失败
- 如何快速格式化重置Mac
- Suse12网络设置
- Phython 数据类型
- 学生信息管理系统V1.0
- 微信怎么防封几率大_域名被墙有哪些处理方法?域名被微信封了该怎么解决?
- hdu 1524 A Chess Game 博弈
- C1083: 无法打开包括文件: plugin.moc: No such file or directory