当前位置:网站首页>Custom filters and interceptors implement ThreadLocal thread closure
Custom filters and interceptors implement ThreadLocal thread closure
2022-08-10 12:33:00 【Trouvailless】
线程封闭
线程封闭一般通过以下三个方法:
- 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();
}
}
复制代码请求访问验证
访问调用接口,控制台输出如下:

本文内容到此结束了,
边栏推荐
- How many constants and data types do you remember?
- Dining (web stream)
- LeetCode 109. Sorted Linked List Conversion Binary Search Tree
- IP地址分类以及网络地址的计算(子网划分、超网划分)[通俗易懂]
- 嘉为蓝鲸荣获工信部“数字技术融合创新应用解决方案”
- Servlet---解决post请求中中文乱码问题
- tommy's spell
- 48 the mysql database
- Apple bucks the trend and expands iPhone 14 series stocking, with a total of 95 million units
- 第六届”蓝帽杯“全国大学生网络安全技能大赛半决赛部分WriteUp
猜你喜欢

爱可可AI前沿推介(8.10)

Data Analysis of Time Series (5): Simple Prediction Method

基于PLECS的离网(孤岛)并联逆变器的Droop Control下垂控制仿真

So delicious!Since using this interface artifact, my team efficiency has increased by 60%!

IM即时通讯开发WebSocket从入门到精通

A detailed explanation of implementation api embed

加密游戏:游戏的未来

mpf6_Time Series Data_quandl_更正kernel PCA_AIC_BIC_trend_log_return_seasonal_decompose_sARIMAx_ADFull

mpf6_Time Series Data_quandl_correct kernel PCA_AIC_BIC_trend_log_return_seasonal_decompose_sARIMAx_ADFull

LT8911EXB MIPI CSI/DSI to EDP signal conversion
随机推荐
An enhanced dynamic packet buffer management.论文核心部分
LeetCode 61. Rotating linked list
Chapter9 : De Novo Molecular Design with Chemical Language Models
LT8911EXB MIPI CSI/DSI转EDP信号转换
【集合】HashSet和ArrayList的查找Contains()时间复杂度
如何让别人看不懂你的 JS 代码?把你当大佬!
LeetCode 19. Delete the Nth last node of the linked list
一文详解 implementation api embed
搜索--01
IM即时通讯开发WebSocket从入门到精通
Accumulated and thin hair!Safety Dog has once again obtained the certification of scientific and technological achievements transformation!
百度用户产品流批一体的实时数仓实践
有哪些好用的性能测试工具推荐?性能测试报告收费标准
开源的作者,也有个生活问题
Excel function formulas - HLOOKUP function
Redis常用命令
Crypto Gaming: The Future of Gaming
技术人必看!数据治理是什么?它对数据中台建设重要吗?
Flutter气泡框实现
因为找不到lombok而找不到符号log