当前位置:网站首页>自定义过滤器和拦截器实现ThreadLocal线程封闭
自定义过滤器和拦截器实现ThreadLocal线程封闭
2022-08-09 15:07:00 【InfoQ】
线程封闭
- Ad-hoc线程封闭:程序控制实现,最糟糕,忽略
- 堆栈封闭:局部变量,无并发问题
- ThreadLocal线程封闭:特别好的封闭方法
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();
}
}自定义过滤器
/**
* <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() {
}
}自定义拦截器
/**
* <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();
}
}请求访问验证
边栏推荐
猜你喜欢

第二章:创建交互式地图(2.4-2.6)

Nacos注册中心 Feign远程调用 Gateway服务网关

Why does a four-byte float represent a wider range than an eight-byte long

初始C语言(2) C生万物

(一)BFC

Chapter 2: Creating Interactive Maps (2.4-2.6)

MySQL必知必会(二)

Anatomy of Storage Size, Value Range, and Output Format of Basic Data Types in C Language

Go语言基础(十四):单元测试

2022华数杯C题:插层熔喷非织造材料的性能控制研究 - 思路
随机推荐
字典树、并查集相关:实现Trie、搜索推荐系统、朋友圈、被围绕的区域(未做) ...
js中的Date对象 及 将时间戳转换为yy-mm-dd hh:mm:ss格式的方法
线性表之顺序表
继承关系下构造方法的访问特点
C语言基本数据类型的存储大小、取值范围、输出格式的解剖
Three ways to find prime numbers
Mysql学习(三)
设计一个登录小程序(while和getchar实现)
第二章:创建交互式地图(2.4-2.6)
2022华数杯建模A题思路解析
三栏布局:左右固定宽,中间自适应的几种方式
5. Visualizing Geospatial Data
Why does a four-byte float represent a wider range than an eight-byte long
kubernetes架构原则和对象设计
初始C语言(2) C生万物
投入C语言
1. Introducing GEE and Geemap
4. Using Local Geospatial Data
学编程的第十天
Detailed explanation of three pieces in C language