当前位置:网站首页>自定义过滤器和拦截器实现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(); }}
请求访问验证
访问调用接口,控制台输出如下:
边栏推荐
- 单片机:温度控制DS18B20
- static linking and dynamic linking
- 电气工程的标准是什么
- Chapter 5: Activiti process shunting judgment, judging to go to different task nodes
- Latex如何控制表格的宽度和高度
- 拓朴排序例题
- [Office] Collection of Microsoft Office download addresses (offline installation and download of Microsoft's official original version)
- 2022技能大赛训练题:交换机snmp配置
- 【综合类型第 35 篇】程序员的七夕浪漫时刻
- DocuWare平台——文档管理的内容服务和工作流自动化的平台详细介绍(下)
猜你喜欢
2022 Huashu Cup Mathematical Modeling Question A Optimization Design Ideas for Ring Oscillators Code Sharing
单片机:温度控制DS18B20
In-depth understanding of timeout settings for Istio traffic management
Dynamics 365Online PDF导出及打印
Getting started with Polkadot parachain development, this article is enough
Confessing in the era of digital transformation: Mai Cong Software allows enterprises to use data in the easiest way
产品太多了,如何实现一次登录多产品互通?
Our Web3 Entrepreneurship Project, Yellow
登录功能和退出功能(瑞吉外卖)
Common operations of oracle under linux and daily accumulation of knowledge points (functions, timed tasks)
随机推荐
Go编译原理系列6(类型检查)
60行从零开始自己动手写FutureTask是什么体验?
Header file search rules when compiling with GCC
[Strong Net Cup 2022] WP-UM
LeetCode 216. Combined Sum III (2022.08.04)
R语言使用yardstick包的pr_curve函数评估多分类(Multiclass)模型的性能、查看模型在多分类每个分类上的ROC曲线(precision(精准率),R代表的是recall(召回率)
第八章:activiti多用户任务分配
解决【命令行/终端】颜色输出问题
Getting started with Polkadot parachain development, this article is enough
How can project cost control help project success?
012_SSS_ Improving Diffusion Model Efficiency Through Patching
MySQL transactions
第九章:activit内置用户组设计与组任务分配和IdentityService接口的使用
结合“xPlus”探讨软件架构的创新与变革
2022华数杯数学建模思路分析交流
《分布式云最佳实践》分论坛,8 月 11 日深圳见
Introduction to SD NAND Flash!
Microcontroller: temperature control DS18B20
poj2935 Basic Wall Maze (2016xynu暑期集训检测 -----D题)
Score interview (1)----related to business