当前位置:网站首页>自定义过滤器和拦截器实现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(); }}请求访问验证
访问调用接口,控制台输出如下:
边栏推荐
- 记2022年七夕感慨
- 2022 Huashu Cup Mathematical Modeling Question A Optimization Design Ideas for Ring Oscillators Code Sharing
- Getting started with Polkadot parachain development, this article is enough
- Is digital transformation a business buy-in?
- 第五章:redis持久化,包括rdb和aof两种方式[通俗易懂]
- R语言使用yardstick包的pr_curve函数评估多分类(Multiclass)模型的性能、查看模型在多分类每个分类上的ROC曲线(precision(精准率),R代表的是recall(召回率)
- Score interview (1)----related to business
- HDD杭州站•ArkUI让开发更灵活
- nyoj754 黑心医生 结构体优先队列
- 七夕来袭!还要做CDH数据迁移怎么办?来看看DistCp
猜你喜欢

Create a Dapp, why choose Polkadot?

Microcontroller: temperature control DS18B20

我们的Web3创业项目,黄了

Getting started with Polkadot parachain development, this article is enough

2022华数杯数学建模A题环形振荡器的优化设计思路思路代码分享

深入理解 Istio 流量管理的超时时间设置

60行从零开始自己动手写FutureTask是什么体验?

工程设备在线监测管理系统自动预警功能

阿里全新推出:微服务突击手册,把所有操作都写出来了PDF

The host computer develops C# language: simulates the STC serial port assistant to receive the data sent by the microcontroller
随机推荐
Where is your most secretive personality?
How to choose coins and determine the corresponding strategy research
【翻译】混沌网+SkyWalking:为混沌工程提供更好的可观察性
GCC编译的时候头文件搜索规则
负载均衡应用场景
[Android]如何使用RecycleView in Kotlin project
Technical dry goods | Hausdorff distance for image segmentation based on MindSpore
GPU-CUDA-图形渲染分析
【综合类型第 35 篇】程序员的七夕浪漫时刻
The host computer develops C# language: simulates the STC serial port assistant to receive the data sent by the microcontroller
第六章:activiti流程分流判断之排它网关和并行网关
字节一面:TCP 和 UDP 可以使用同一个端口吗?
一个栈的输入序列为1 2 3 4 5 的出站顺序的理解
DocuWare平台——文档管理的内容服务和工作流自动化的平台详细介绍(下)
如何测试一下现场的备机失败,转发主机的场景?
HDD杭州站•ArkUI让开发更灵活
化繁为简!阿里新产亿级流量系统设计核心原理高级笔记(终极版)
[Office] Collection of Microsoft Office download addresses (offline installation and download of Microsoft's official original version)
What is SPL?
气象数据数据处理实例——matlab字符串切割匹配与R语言日期匹配(数据拼接)