当前位置:网站首页>自定义过滤器和拦截器实现ThreadLocal线程封闭
自定义过滤器和拦截器实现ThreadLocal线程封闭
2022-08-05 10:47:00 【华为云】
线程封闭
线程封闭一般通过以下三个方法:
- Ad-hoc线程封闭:程序控制实现,最糟糕,忽略
- 堆栈封闭:局部变量,无并发问题
- ThreadLocal线程封闭:特别好的封闭方法
方法2是最常用的,变量定义在接口内,本文主要讲解方法三,SpringBoot项目通过自定义过滤器和拦截器实现ThreadLocal线程封闭。实现Filter接口自定义过滤器和继承HandlerInterceptorAdapter自定义拦截器。
ThreadLocal线程封闭实现步骤
封装ThredLocal的方法
/** * <p>自定义RequestHolder</p></p> * * @Author zjq * @Date 2021/12 */public class RequestHolder { private final static ThreadLocal<Long> requestHolder = new ThreadLocal<>(); public static void set(Long id) { requestHolder.set(id); } public static Long get() { return requestHolder.get(); } public static void remove() { requestHolder.remove(); }}
自定义过滤器
自定义定义拦截器继承Filter接口,实现ThredLocal.add()方法
/** * <p>自定义过滤器</p> * * @Author zjq * @Date 2021/12/7 */@Slf4jpublic class HttpFilter implements Filter { /** * 为Filter初始化 提供支持 * * @param filterConfig * @throws ServletException */ @Override public void init(FilterConfig filterConfig) throws ServletException { } /** * 拦截到要执行的请求时,doFilter就会执行。这里我们可以写对请求和响应的预处理。 * FilterChain把请求和响应传递给下一个 Filter处理 * * @param servletRequest * @param servletResponse * @param filterChain * @throws IOException * @throws ServletException */ @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { //把普通servlet强转成httpServlet HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest; Long threadId = Thread.currentThread().getId(); log.info("do filter,threadId:{} servletPath:{}", threadId, httpServletRequest.getServletPath()); //把当前线程id放入requestHolder RequestHolder.set(threadId); //放行 filterChain.doFilter(httpServletRequest, servletResponse); } /** * Filter 实例销毁前的准备工作 */ @Override public void destroy() { }}
自定义拦截器
自定义拦截器在线程使用完毕后移除ThredLocal中内容,避免内存溢出
/** * <p>自定义拦截器</p> * * @Author zjq * @Date 2021/12/7 */@Slf4jpublic class HttpInterceptor extends HandlerInterceptorAdapter { /** * 拦截处理程序的执行。在 HandlerMapping 确定合适的处理程序对象之后,在 HandlerAdapter 调用处理程序之前调用。 * @param request * @param response * @param handler * @return * @throws Exception */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { log.info("preHandle执行。。。"); return true; } /** * 请求处理完成后(渲染视图后)的回调。将在处理程序执行的任何结果上调用,从而允许进行适当的资源清理。 * @param request * @param response * @param handler * @param ex * @throws Exception */ @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { RequestHolder.remove(); log.info("afterCompletion执行。。。"); return; }}
Application类启动类中配置自定义过滤器和拦截器
/** * * @author zjq */@SpringBootApplicationpublic class Application extends WebMvcConfigurationSupport { public static void main(String[] args) { SpringApplication.run(ConcurrencyApplication.class, args); } /** * 自定义过滤器 * @return */ @Bean public FilterRegistrationBean filterRegistrationBean(){ FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(); filterRegistrationBean.setFilter(new HttpFilter()); //设置自定义过滤器拦截的url filterRegistrationBean.addUrlPatterns("/threadLocal/*"); return filterRegistrationBean; } /** * 定义自定义拦截器原先需要继承WebMvcConfigurerAdapter * SpringBoot2.0后WebMvcConfigurerAdapter被定义成过时了,推荐使用继承WebMvcConfigurationSupport * @param registry */ @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new HttpInterceptor()).addPathPatterns("/**"); }}
定义调用接口
/** * ThreadLocal测试controller * @author zjq */@Controller@RequestMapping("/threadLocal")public class ThreadLocalController { @RequestMapping("/test") @ResponseBody public Long test() { return RequestHolder.get(); }}
请求访问验证
访问调用接口,控制台输出如下:
边栏推荐
- flutter 服务器返回数据判断是否为空
- nyoj86 找球号(一) set容器和二分 两种解法
- LeetCode 216. Combined Sum III (2022.08.04)
- [Office] Collection of Microsoft Office download addresses (offline installation and download of Microsoft's official original version)
- Meteorological data processing example - matlab string cutting matching and R language date matching (data splicing)
- 上位机开发C#语言:模拟STC串口助手接收单片机发送数据
- How can project cost control help project success?
- What are the standards for electrical engineering
- 【加密解密】明文加密解密-已实现【已应用】
- sqlserver编写通用脚本实现获取一年前日期的方法
猜你喜欢
【OpenCV】-仿射变换
使用Windbg过程中两个使用细节分享
The century-old Nordic luxury home appliance brand ASKO smart wine cabinet in the three-temperature area presents the Chinese Valentine’s Day, and tastes the love of the delicacy
2022华数杯数学建模A题环形振荡器的优化设计思路思路代码分享
教你本地编译运行一个IDEA插件,在IDEA里聊天、下棋、斗地主!
【MindSpore Easy-Diantong Robot-01】You may have seen many knowledge quiz robots, but this one is a bit different
In-depth understanding of timeout settings for Istio traffic management
上位机开发C#语言:模拟STC串口助手接收单片机发送数据
abc262-D(dp)
GPU-CUDA-图形渲染分析
随机推荐
2022 Huashu Cup Mathematical Modeling Question A Optimization Design Ideas for Ring Oscillators Code Sharing
STM32+ULN2003 drives 28BYJ4 stepper motor (forward and reverse according to the number of turns)
nyoj754 黑心医生 结构体优先队列
The founder of the DFINITY Foundation talks about the ups and downs of the bear market, and where should DeFi projects go?
拓朴排序例题
攻防世界-PWN-new_easypwn
Login function and logout function (St. Regis Takeaway)
Where is your most secretive personality?
Still looking for a network backup resources?Hurry up to collect the following network backup resource search artifact it is worth collecting!
Ali's new launch: Microservices Assault Manual, all operations are written out in PDF
2022华数杯数学建模A题环形振荡器的优化设计思路思路代码分享
trie树模板
nyoj86 找球号(一) set容器和二分 两种解法
gradle尚硅谷笔记
Is digital transformation a business buy-in?
FPGA: Basic Getting Started LED Lights Blinking
第五章:多线程通信—wait和notify
【翻译】混沌网+SkyWalking:为混沌工程提供更好的可观察性
技术干货 | 基于 MindSpore 实现图像分割之豪斯多夫距离
The fuse: OAuth 2.0 four authorized login methods must read