Java自定义过滤器和 * 实现ThreadLocal线程封闭
作者:共饮一杯无 发布时间:2023-09-19 04:29:04
标签:Java,ThreadLocal,线程封闭
线程封闭
线程封闭一般通过以下三个方法:
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
*/
@Slf4j
public 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
*/
@Slf4j
public 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
*/
@SpringBootApplication
public 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();
}
}
请求访问验证
访问调用接口http://localhost:8080/threadLocal/test,控制台输出如下:
来源:https://juejin.cn/post/7128195148076302350
0
投稿
猜你喜欢
- 这里以list为介绍:private static readonly T[] s_emptyArray = new T[0];public
- 1、多态性多态性是面向对象的最后一个特征,它本身主要分为两个方面: 方法的多态性:重载与覆写1、重载:同一个方法名称,根据参数类型以及个数完
- Mybatis-plus全局id生成策略在配置文件中加入以下代码后就不需要在实体类种的id上添加@TableId(value = “id”,
- 最长公共子序列(Longest Common Subsequence)定义:两个或多个已知数列的子序列集合中最长的就是最长公共子序列。其实说
- 以一个web项目为例,代码是可以移植的首先要导入mail.jar包,然后创建自己的类1:HTMLSender类package com.txq
- 本文实例为大家分享了Unity动画混合树实例代码,供大家参考,具体内容如下先看效果游戏动画中的一项常见任务是在两个或更多相似运动之间进行混合
- 一.使用MSScriptControl 到微软的网站上下载Windows Script Control,它是一个ActiveX(R) 控件,
- 本文主要为大家整理Java常见的面试题,供大家参考,具体内容如下1. Java中sleep和wait的区别① 这两个方法来自不同
- 最近公司项目需要在WebView上调用手机系统相册来上传图片,开发过程中发现在很多机器上无法正常唤起系统相册来选择图片。解决问题之前我们先来
- ViewStub可以在运行时动态的添加布局。帮助文档给定的定义是:"A ViewStub is an invisible, zer
- 1、未配置之前2、开始配置 2.1 新建一个unauth.html<!DOCTYPE html><html la
- 前言支付宝推出一个沙箱环境,能够很好的模拟支付宝支付,并且还提供了demo,但demo是一个普通web项目,怎么整合到Spring Boot
- 本文实例讲述了C#后台创建控件并获取值的方法。分享给大家供大家参考。具体实现方法如下:前台代码:<form id="form
- 1、什么是const? 常类型是指使用类型修饰符const说明的类型,常类型的变量或对象的值是不能被更新的。(当然,我们可以偷梁
- 前言在 App 开发过程中,ListView 是 比较很常见的控件,用来处理 列表类的数据展示。当然 Flutter 也是支持的,由于 Fl
- 导读Lombok:可以让你的POJO代码特别简洁,不止简单在BO/VO/DTO/DO等大量使用,还有设计模式,对象对比等MybatisPlu
- JPA JpaRepository接口的使用SpringData的所有接口CrudRepository接口 ,其中提供了这些方法提供使用,同
- 知识点:1.使用SQL Helper创建数据库2.数据的增删查改(PRDU:Put、Read、Delete、Update)背景知识:上篇文章
- 下面我给各位朋友整理了一篇C# 获取图片文件扩展名的例子,这里方法都非常的简单,我们只用到了image.RawFormat.Guid就实现了
- Runtime.getRuntime().exec 路径包含空格1. 现象java代码通过Runtime.getRuntime().exec