总体理解
- 听起来如果是权限控制时使用ThreadLocal,并不是出于减少查询Redis数据库的目的,而是为了保证数据完整性,Thread线程独占某个资源避免高并发时出现数据异常和串号的情况。
Controller
@RestController@RequestMapping("/threadLocal")public class ThreadLocalController {@RequestMapping("/test")@ResponseBodypublic Long test() {return RequestHolder.getId();}}
RequestHolder
public class RequestHolder {private final static ThreadLocal<Long> requestHolder = new ThreadLocal<>();public static void add(long id) {requestHolder.set(id);}public static Long getId() {return requestHolder.get();}public static void remove() {requestHolder.remove();}}
HttpFilter
@Slf4jpublic class HttpFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {HttpServletRequest request = (HttpServletRequest) servletRequest;log.info("do filter, {}, {}", Thread.currentThread().getId(), request.getServletPath());//在ThreadLocal中添加当前线程的idRequestHolder.add(Thread.currentThread().getId());filterChain.doFilter(servletRequest, servletResponse);}@Overridepublic void destroy() {}}
HttpInterceptor
真实使用的时候
@Slf4jpublic class HttpInterceptor extends HandlerInterceptorAdapter {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {log.info("preHandle");return true;}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {log.info("ThreadId:"+RequestHolder.getId());RequestHolder.remove();log.info("afterCompletion");return;}}
DemoApplication
@SpringBootApplication(scanBasePackages = "Controller")public class DemoApplication extends WebMvcConfigurerAdapter {public static void main(String[] args){SpringApplication.run(DemoApplication.class, args);}@Beanpublic FilterRegistrationBean httpFilter() {FilterRegistrationBean registrationBean = new FilterRegistrationBean();registrationBean.setFilter(new HttpFilter());registrationBean.addUrlPatterns("/threadLocal/*");return registrationBean;}@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new HttpInterceptor()).addPathPatterns("/**");}}
