当前位置:网站首页>Custom filters and interceptors implement ThreadLocal thread closure
Custom filters and interceptors implement ThreadLocal thread closure
2022-08-05 10:50:00 【HUAWEI CLOUD】
线程封闭
线程封闭一般通过以下三个方法:
- 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(); }}请求访问验证
访问调用接口,控制台输出如下:
边栏推荐
- 反射修改jsessionid实现Session共享
- Latex如何控制表格的宽度和高度
- FPGA: Use of the development environment Vivado
- [Translation] Chaos Net + SkyWalking: Better observability for chaos engineering
- Chapter 5: Multithreaded Communication—wait and notify
- SkiaSharp 之 WPF 自绘 投篮小游戏(案例版)
- STM32+ULN2003 drives 28BYJ4 stepper motor (forward and reverse according to the number of turns)
- Go编译原理系列6(类型检查)
- Leetcode刷题——623. 在二叉树中增加一行
- nyoj86 找球号(一) set容器和二分 两种解法
猜你喜欢

【加密解密】明文加密解密-已实现【已应用】

智能算力的枢纽如何构建?中国云都的淮海智算中心打了个样

This notebook of concurrent programming knowledge points strongly recommended by Ali will be a breakthrough for you to get an offer from a big factory

【OpenCV】-仿射变换

RT - Thread record (a, RT, RT Thread version - Thread Studio development environment and cooperate CubeMX quick-and-dirty)

用KUSTO查询语句(KQL)在Azure Data Explorer Database上查询LOG实战

《分布式云最佳实践》分论坛,8 月 11 日深圳见

反射修改jsessionid实现Session共享
![[Strong Net Cup 2022] WP-UM](/img/3d/caeab05ddca278af274dbf6e2f8ba1.png)
[Strong Net Cup 2022] WP-UM

STM32+ULN2003 drives 28BYJ4 stepper motor (forward and reverse according to the number of turns)
随机推荐
lvgl 实现状态提示图标自动对齐补位显示
Latex如何控制表格的宽度和高度
Score interview (1)----related to business
一个栈的输入序列为1 2 3 4 5 的出站顺序的理解
Voice-based social software development - making the most of its value
什么是 DevOps?看这一篇就够了!
STM32 entry development: write XPT2046 resistive touch screen driver (analog SPI)
第四章:activiti RuntimeService设置获和取流程变量,及与taskService的区别,开始和完成任务时设置流程变量[通俗易懂]
【AGC】增长服务1-远程配置示例
FPGA:基础入门按键控制LED灯
Introduction to SD NAND Flash!
2022杭电杯超级联赛(5)
记2022年七夕感慨
The founder of the DFINITY Foundation talks about the ups and downs of the bear market, and where should DeFi projects go?
012_SSS_ Improving Diffusion Model Efficiency Through Patching
Is digital transformation a business buy-in?
How to choose coins and determine the corresponding strategy research
nyoj754 黑心医生 结构体优先队列
【OpenCV】-仿射变换
[Strong Net Cup 2022] WP-UM