当前位置:网站首页>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(); }}
请求访问验证
访问调用接口,控制台输出如下:
边栏推荐
- 第五章:多线程通信—wait和notify
- 这份阿里强推的并发编程知识点笔记,将是你拿大厂offer的突破口
- Oracle 19.3 restart 环境
- 大佬们 我是新手,我根据文档用flinksql 写个简单的用户访问量的count 但是执行一次就结束
- Is digital transformation a business buy-in?
- 用KUSTO查询语句(KQL)在Azure Data Explorer Database上查询LOG实战
- 导火索:OAuth 2.0四种授权登录方式必读
- Complete image segmentation efficiently based on MindSpore and realize Dice!
- lvgl 实现状态提示图标自动对齐补位显示
- sqlserver编写通用脚本实现获取一年前日期的方法
猜你喜欢
阿里全新推出:微服务突击手册,把所有操作都写出来了PDF
智能算力的枢纽如何构建?中国云都的淮海智算中心打了个样
SQL Outer Join Intersection, Union, Difference Query
【综合类型第 35 篇】程序员的七夕浪漫时刻
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实战
深入理解 Istio 流量管理的超时时间设置
PostgreSQL 2022 报告:流行度上涨,开源、可靠性和扩展是关键
Complete image segmentation efficiently based on MindSpore and realize Dice!
Ali's new launch: Microservices Assault Manual, all operations are written out in PDF
随机推荐
012年通过修补_sss_提高扩散模型效率
The host computer develops C# language: simulates the STC serial port assistant to receive the data sent by the microcontroller
反射修改jsessionid实现Session共享
Where is your most secretive personality?
Microcontroller: temperature control DS18B20
three objects are arranged in a spherical shape around the circumference
MySQL transactions
FPGA: Basic Getting Started LED Lights Blinking
Go编译原理系列6(类型检查)
OpenHarmony如何查询设备类型
PCB layout must know: teach you to correctly lay out the circuit board of the op amp
Dynamics 365Online PDF导出及打印
How to choose coins and determine the corresponding strategy research
第六章:activiti流程分流判断之排它网关和并行网关
flutter 服务器返回数据判断是否为空
第五章:activiti流程分流判断,判断走不同的任务节点
PostgreSQL 2022 报告:流行度上涨,开源、可靠性和扩展是关键
化繁为简!阿里新产亿级流量系统设计核心原理高级笔记(终极版)
nyoj754 黑心医生 结构体优先队列
nyoj86 找球号(一) set容器和二分 两种解法