当前位置:网站首页>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();
}
}
复制代码
请求访问验证
访问调用接口,控制台输出如下:
本文内容到此结束了,
边栏推荐
- 浮动及其特点
- LeetCode 237. 删除链表中的节点
- Threshold-based filtering buffer management scheme in a shared buffer packet switch core part of the paper
- 蚂蚁金服+拼多多+抖音+天猫(技术三面)面经合集助你拿大厂offer
- 十八、一起学习Lua 调试(Debug)
- 孩子自律性不够?猿辅导:计划表要注意“留白”给孩子更多掌控感
- Does face attendance choose face comparison 1:1 or face search 1:N?
- LeetCode 146. LRU Cache
- LeetCode 21. Merge two ordered linked lists
- 被面试官问到消息队列的丢失、重复与积压问题该如何回答
猜你喜欢
CV复习:空洞卷积
可视化服务编排在金融APP中的实践
Chapter 5 virtual memory
dedecms supports one-click import of Word content
加密游戏:游戏的未来
Does your child lack self-discipline?Ape Counseling: Pay attention to "blank" in the schedule to give children more control
Analysis of the implementation principle of UUID from the perspective of source code
十八、一起学习Lua 调试(Debug)
Network Fundamentals (Section 1)
IDC第一的背后,阿里云在打造怎样的一朵“视频云”?
随机推荐
【Redis】内存回收策略
IDC第一的背后,阿里云在打造怎样的一朵“视频云”?
A detailed explanation of implementation api embed
The author of open source also has a life problem
Does face attendance choose face comparison 1:1 or face search 1:N?
LeetCode 25. A set of K flipped linked lists
Threshold-based filtering buffer management scheme in a shared buffer packet switch论文核心部分
HDU 4135:Co-prime (容斥原理)
LeetCode 86. 分隔链表
传三星3nm斩获第二家客户,目前产能已供不应求
tommy's spell
因为找不到lombok而找不到符号log
堪称神级的阿里巴巴“高并发”教程——基础+实战+源码+面试+架构 全包了
It is rumored that Samsung 3nm has won the second customer, and the current production capacity is in short supply
mpf6_Time Series Data_quandl_correct kernel PCA_AIC_BIC_trend_log_return_seasonal_decompose_sARIMAx_ADFull
mpf6_Time Series Data_quandl_更正kernel PCA_AIC_BIC_trend_log_return_seasonal_decompose_sARIMAx_ADFull
毕业总结
迈矽科推出高性能77GHz毫米波雷达芯片,尚未量产就已获数万颗订单
48MySQL数据库基础
Servlet---解决post请求中中文乱码问题